shhh <- suppressPackageStartupMessages # It's a library, so shhh!
shhh(library( mgcv ))
shhh(library(dplyr))
shhh(library(ggplot2))
shhh(library(lme4))
shhh(library(tidymv))
shhh(library(gamlss))
shhh(library(gsubfn))
shhh(library(lmerTest))
shhh(library(tidyverse))
shhh(library(boot))
shhh(library(rsample))
shhh(library(plotrix))
shhh(library(ggrepel))
shhh(library(mgcv))
shhh(library(brms))
shhh(library(bayesplot))
shhh(library(patchwork))
shhh(library(MASS))
shhh(library(tidyr))
shhh(library(extraDistr))
shhh(library(purrr))
# For exercises with Stan code
shhh(library(rstan))
options(mc.cores = parallel::detectCores())
rstan_options(auto_write = FALSE)
shhh(library(car))
shhh(library(coda))
shhh(library(gridExtra))
theme_set(theme_bw())
options(digits=4)
options(scipen=999)
set.seed(444)
pipe_message = function(.data, status) {message(status); .data}
Read in MoTR Data
rate = 160
file_prefix = "../data/provo_f160/"
fnames = list.files(path=file_prefix)
df = data.frame()
for (f in fnames) {
temp = read.csv(paste0(file_prefix, "/", f)) %>%
mutate(subj = str_remove(f, "_reading_measures.csv"))
df = rbind(df, temp)
}
# Filter out readers whose accuracy to the comprehension questions were less than 80%.
filter_df = df %>%
group_by(para_nr, subj) %>% summarise(correct = if_else(unique(correctness) == 1, 1, 0)) %>% ungroup() %>%
drop_na() %>%
group_by(subj) %>% summarise(p_correct = mean(correct)) %>% ungroup() %>%
mutate(p_correct = round(p_correct, digits = 2))
`summarise()` has grouped output by 'para_nr'. You can override using the `.groups` argument.
filter_df = filter_df %>% filter(p_correct < 0.8)
filter_list = filter_df$subj
pilot_exceptions <- c("reader_255", "reader_256", "reader_259", "reader_261", "reader_262", "reader_263")
raw_df = df %>%
filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
mutate(word = str_trim(word)) %>%
mutate(subj = str_remove(subj, "reader_")) %>%
mutate(subj = as.character(subj)) %>%
mutate(FPReg = if_else(total_duration == 0, -1, FPReg)) %>% #If the word is skipped we can't say that it wasn't regressed on the first pass. Set to a "NA"
mutate(skip = if_else(FPFix == 1, 0, 1)) %>% # use the same defination as in provo paper
dplyr::select(subj, expr_id, cond_id, para_nr, word, word_nr, first_duration, total_duration, gaze_duration, go_past_time, FPReg, skip) %>%
gather(metric, value, 7:10) %>%
group_by(para_nr, subj, metric, cond_id, expr_id) %>%
mutate(fixed = if_else(value > 0, 1, 0),
n_fixed = sum(fixed),
n_words = n()) %>%
ungroup() %>%
mutate(fix_threshold = n_fixed > (n_words / 5)) %>%
mutate(skimming = if_else(fix_threshold == F,T, F)) %>%
filter(skimming == F) %>%
spread(metric, value) %>%
dplyr::select(-fixed, -n_fixed, -n_words, -fix_threshold, -skimming)
length(unique(raw_df$subj))
[1] 98
# View(raw_df)
df %>%
filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
filter(FPReg >= 0) %>%
dplyr::select(FPReg) %>%
drop_na() %>%
summarise( m = mean(FPReg))
df %>%
filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
dplyr::select(FPFix) %>%
drop_na() %>%
summarise( m = mean(FPFix))
NA
NA
View(raw_df)
# Average across subjects
motr_agg_df = raw_df %>%
gather(metric, value, 7:12) %>%
filter(value >= 0) %>% #Removes the "NA" values for FPReg
# ==== Remove skipped words
mutate(zero = if_else(!metric %in% c("FPReg", "skip") & value == 0,T, F)) %>%
filter(zero == F) %>%
drop_na() %>%
group_by(para_nr, word_nr, word, metric) %>%
# === Remove outliers > 3SD
# mutate(outlier = if_else(metric != "FPReg" & value > (mean(value) + 3 * sd(value)), T, F)) %>% filter(outlier == F) %>%
summarise(value = mean(value), nsubj = length(unique(subj))) %>%
ungroup() %>%
arrange(para_nr, word_nr) %>%
rename(text_id = para_nr, word_text_idx = word_nr, motr_value = value)
`summarise()` has grouped output by 'para_nr', 'word_nr', 'word'. You can override using the `.groups` argument.
# View(motr_agg_df)
Comparison to Provo
# Read in Provo surprisal, frequency and length data
provo_modeling_df = read.csv("../data/provo_stats.csv") %>%
dplyr::select(text_id, sent_id, trigger_idx, word, freq, surp, len) %>%
rename(word_idx = trigger_idx)
provo_modeling_df
NA
# Read in Provo eyetracking data
provo_raw_df = read.csv("../data/provo_eyetracking.csv")
# unique(provo_raw_df$Participant_ID)
# length(unique(provo_raw_df$Participant_ID))
provo_eyetracking_df = provo_raw_df %>%
dplyr::select(Participant_ID, Text_ID, Sentence_Number, Word_In_Sentence_Number, Word, Word_Number, IA_FIRST_FIX_PROGRESSIVE, IA_FIRST_RUN_DWELL_TIME, IA_DWELL_TIME, IA_REGRESSION_PATH_DURATION, IA_REGRESSION_OUT, IA_SKIP) %>%
rename( #first_duration = IA_FIRST_FIXATION_DURATION,
gaze_duration = IA_FIRST_RUN_DWELL_TIME,
total_duration = IA_DWELL_TIME,
go_past_time = IA_REGRESSION_PATH_DURATION,
subj = Participant_ID,
text_id = Text_ID,
sent_id = Sentence_Number,
word_idx = Word_In_Sentence_Number,
word_text_idx = Word_Number, # IA_ID?
word = Word, # Word?
FPReg = IA_REGRESSION_OUT,
skip = IA_SKIP,
ff_progressive = IA_FIRST_FIX_PROGRESSIVE) %>%
mutate(first_duration = gaze_duration) %>%
mutate(gaze_duration = if_else(ff_progressive == 0, 0, as.double(gaze_duration)),
go_past_time = if_else(ff_progressive == 0, 0, as.double(go_past_time))) %>%
dplyr::select(-ff_progressive) %>%
mutate(
gaze_duration = if_else(total_duration == 0, 0, as.double(gaze_duration)),
go_past_time = if_else(total_duration == 0, 0, as.double(go_past_time)),
FPReg = if_else(total_duration == 0, -1, as.double(FPReg)),
first_duration = if_else(total_duration == 0, 0, as.double(first_duration)),
) %>%
gather(metric, value, 7:12) %>%
filter(value >= 0) %>% # filter skipped word in eye tracking data for FPReg
# ==== Remove skipped words
mutate(zero = if_else(!metric %in% c("FPReg", "skip") & value == 0,T, F)) %>%
filter(zero == F) %>%
# mutate(value = if_else(is.na(value), as.integer(0), as.integer(value))) %>%
# mutate(value = if_else(metric != "FPReg" & is.na(value), as.integer(0), as.integer(value))) %>%
drop_na() %>%
mutate(word = str_trim(word)) %>%
mutate(subj = str_remove(subj, "Sub")) %>%
mutate(subj = as.integer(subj)) %>%
group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
# === Remove outliers > 3SD
# mutate(outlier = if_else(! metric %in% c("FPReg", "skip") & value > (mean(value) + 3 * sd(value) ), T, F)) %>%
# filter(outlier == F) %>%
ungroup() #%>%
# Aggregate cross-participant data for all subjects
provo_eyetracking_agg_df = provo_eyetracking_df %>%
group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
summarise(value = mean(value),
nsubj = length(unique(subj))) %>%
ungroup()
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
provo_raw_df %>%
dplyr::select(IA_REGRESSION_OUT) %>%
drop_na() %>%
summarise( m = mean(IA_REGRESSION_OUT))
provo_raw_df %>%
dplyr::select(IA_SKIP) %>%
drop_na() %>%
summarise( m = mean(IA_SKIP))
NA
# Split the eyetracking data in two by subjects to see how well it correlates with itself
provo_eyetracking_subj1_df_temp = provo_eyetracking_df %>%
filter(subj <= 42) %>%
mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
summarise(value = mean(value)) %>%
ungroup() %>%
rename(value_1 = value) #%>%
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
# dplyr::select(-sent_id, -word_idx)
provo_eyetracking_subj1_df = merge(provo_eyetracking_subj1_df_temp, motr_agg_df, by=c("text_id", "word_text_idx", "metric")) %>%
arrange(text_id, sent_id, word_idx) %>%
filter(!(text_id == 13 & word_text_idx >= 20 & word_text_idx <= 52)) %>%
filter(!(text_id == 3 & word_text_idx >= 46 & word_text_idx <= 57)) %>%
rename(word = word.y) %>%
dplyr::select(text_id, word_text_idx, metric, word, value_1)
# View(provo_eyetracking_subj1_df)
provo_eyetracking_subj2_df = provo_eyetracking_df %>%
filter(subj > 42) %>%
mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
summarise(value = mean(value)) %>%
ungroup() %>%
rename(value_2 = value)%>%
dplyr::select(-sent_id, -word_idx)
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
# View(provo_eyetracking_subj2_df)
provo_eyetr_grouped_df = merge(provo_eyetracking_subj2_df, provo_eyetracking_subj1_df, by=c("text_id", "word_text_idx", "metric")) %>%
# filter(word.x == word.y) %>%
dplyr::select(-word.y) %>%
# === Remove outliers > 3SD
# group_by(metric) %>%
# mutate(motr_outlier = if_else(! metric %in% c("FPReg", "skip") & value_1 > (mean(value_1) + 3 * sd(value_1) ), T, F)) %>%
# filter(motr_outlier == F) %>%
# mutate(eyetr_outlier = if_else(! metric %in% c("FPReg", "skip") & value_2 > (mean(value_2) + 3 * sd(value_2) ), T, F)) %>%
# filter(eyetr_outlier == F) %>%
# ungroup() %>%
gather(measure, value, c("value_1", "value_2")) #%>%
# dplyr::select(-motr_outlier, -eyetr_outlier)
# View(provo_eyetr_grouped_df)
provo_df = merge(provo_eyetracking_agg_df, provo_modeling_df, by=c("text_id", "sent_id", "word_idx")) %>%
mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
arrange(text_id, sent_id, word_idx) %>%
rename(eyetr_value = value)
provo_df = merge(provo_df, motr_agg_df, by=c("text_id", "word_text_idx", "metric")) %>%
arrange(text_id, sent_id, word_idx) %>%
# almost all the word.x != word.y is because of normalization problem, so we can keep them, instead, deleting some special cases
filter(!(text_id == 13 & word_text_idx >= 20 & word_text_idx <= 52)) %>%
filter(!(text_id == 3 & word_text_idx >= 46 & word_text_idx <= 57)) %>%
# filter(word.x == word) #%>%
dplyr::select(-word.x, -word.y) %>%
# === Remove outliers > 3SD
# group_by(metric) %>%
# mutate(motr_outlier = if_else(! metric %in% c("FPReg", "skip") & motr_value > (mean(motr_value) + 3 * sd(motr_value) ), T, F)) %>%
# filter(motr_outlier == F) %>%
# mutate(eyetr_outlier = if_else(! metric %in% c("FPReg", "skip") & eyetr_value > (mean(eyetr_value) + 3 * sd(eyetr_value) ), T, F)) %>%
# filter(eyetr_outlier == F) %>%
# ungroup() %>%
gather(measure, value, c("eyetr_value", "motr_value")) #%>%
# dplyr::select(-motr_outlier, -eyetr_outlier)
# provo_df
Bayesian – use Stan – motr & eyetr correlation
print("Gaze Duration")
[1] "Gaze Duration"
gd_df = provo_df %>% filter(metric == "gaze_duration") %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value = pmax(eyetr_value, 1),
motr_value = pmax(motr_value, 1)
) %>%
mutate(eyetr_value_log = log(eyetr_value),
motr_value_log = log(motr_value))
print(cor.test(gd_df$eyetr_value, gd_df$motr_value)$estimate)
cor
0.4944
print(cor.test(gd_df$eyetr_value_log, gd_df$motr_value_log)$estimate)
cor
0.5015
# View(gd_df)
gd_df %>%
gather(measure, value, 12:15) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")

NA
# center data around 0.
gd_temp <- gd_df[c("eyetr_value", "motr_value")] %>%
# mutate(eyetr_value = eyetr_value - mean(eyetr_value),
# motr_value = motr_value - mean(motr_value)) %>%
data.matrix()
gd_temp_log <- gd_df[c("eyetr_value_log", "motr_value_log")] %>%
mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log),
motr_value_log = motr_value_log - mean(motr_value_log)) %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(gd_temp, pch = 16, col = "blue",
main = "Not Log-Transformed")
# Plot the second data matrix gd_temp_log
plot(gd_temp_log, pch = 16, col = "red",
main = "Centered Log-Transformed")

gd_data = list(x=gd_temp, N=nrow(gd_temp))
fit_gd = stan(
file="stan_models/bivariate_correlation.stan",
data=gd_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_gd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_gd, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds"))
print("Go Past Time")
[1] "Go Past Time"
gpt_df = provo_df %>% filter(metric == "go_past_time") %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value = pmax(eyetr_value, 1),
motr_value = pmax(motr_value, 1)
) %>%
mutate(eyetr_value_log = log(eyetr_value),
motr_value_log = log(motr_value))
print(cor.test(gpt_df$eyetr_value, gpt_df$motr_value)$estimate)
cor
0.5122
print(cor.test(gpt_df$eyetr_value_log, gpt_df$motr_value_log)$estimate)
cor
0.4607
gpt_df %>%
gather(measure, value, 12:15) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
gpt_temp <- gpt_df[c("eyetr_value", "motr_value")] %>% data.matrix()
gpt_temp_log <- gpt_df[c("eyetr_value_log", "motr_value_log")] %>%
mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log),
motr_value_log = motr_value_log - mean(motr_value_log)) %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gpt_temp
plot(gpt_temp, pch = 16, col = "blue",
main = "Not Log-Transformed")
# Plot the second data matrix gpt_temp_log
plot(gpt_temp_log, pch = 16, col = "red",
main = "Centered Log-Transformed")

# -------fit model go past time ----------
gpt_data = list(x=gpt_temp, N=nrow(gpt_temp))
fit_gpt = stan(
file="stan_models/bivariate_correlation.stan",
data=gpt_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_gpt@stanmodel@dso <- new("cxxdso")
saveRDS(fit_gpt, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds"))
print("Total Duration")
[1] "Total Duration"
td_df = provo_df %>% filter(metric == "total_duration") %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value = pmax(eyetr_value, 1),
motr_value = pmax(motr_value, 1)
) %>%
mutate(eyetr_value_log = log(eyetr_value),
motr_value_log = log(motr_value))
print(cor.test(td_df$eyetr_value, td_df$motr_value)$estimate)
cor
0.5952
print(cor.test(td_df$eyetr_value_log, td_df$motr_value_log)$estimate)
cor
0.5957
td_df %>%
gather(measure, value, 12:15) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
td_temp <- td_df[c("eyetr_value", "motr_value")] %>% data.matrix()
td_temp_log <- td_df[c("eyetr_value_log", "motr_value_log")] %>%
mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log),
motr_value_log = motr_value_log - mean(motr_value_log)) %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(td_temp, pch = 16, col = "blue",
main = "Not Log-Transformed")
# Plot the second data matrix td_temp_log
plot(td_temp_log, pch = 16, col = "red",
main = "Centered Log-Transformed")

# -------fit model total duration ----------
td_data = list(x=td_temp, N=nrow(td_temp))
fit_td = stan(
file="stan_models/bivariate_correlation.stan",
data=td_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_td@stanmodel@dso <- new("cxxdso")
saveRDS(fit_td, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds"))
print("First Pass Regression Prob.")
[1] "First Pass Regression Prob."
reg_df = provo_df %>% filter(metric == "FPReg") %>%
spread(measure, value) %>%
filter(eyetr_value > 0, motr_value > 0) %>%
mutate(eyetr_value = pmax(eyetr_value, 1e-5),
motr_value = pmax(motr_value, 1e-5))
print(cor.test(reg_df$eyetr_value, reg_df$motr_value)$estimate)
cor
0.386
# View(reg_df)
reg_df %>%
gather(measure, value, 12:13) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
reg_temp <- reg_df[c("eyetr_value", "motr_value")] %>% data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(reg_temp, pch = 16, col = "blue",
main = "Not Log-Transformed")

# -------fit model FPReg ----------
reg_data = list(x=reg_temp, N=nrow(reg_temp))
fit_reg = stan(
file="stan_models/bivariate_normal_reg.stan",
data=reg_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_drop0s.rds"))
rank transformation for FPReg
reg_df = provo_df %>% filter(metric == "FPReg") %>%
spread(measure, value) %>%
mutate(
eyetr_value_rank = ifelse(eyetr_value > 0, rank(eyetr_value), NA),
motr_value_rank = ifelse(motr_value > 0, rank(motr_value), NA)
) %>%
drop_na()
# mutate(
# eyetr_value_rank = rank(eyetr_value, ties.method = "average"),
# motr_value_rank = rank(motr_value, ties.method = "average")
# )
# View(reg_df)
print(cor.test(reg_df$eyetr_value_rank, reg_df$motr_value_rank)$estimate)
print(cor.test(reg_df$eyetr_value_rank, reg_df$motr_value_rank, method = "kendall"))
reg_df %>%
gather(measure, value, 14:15) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
reg_temp <- reg_df[c("eyetr_value_rank", "motr_value_rank")] %>% data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix td_temp
plot(reg_temp, pch = 16, col = "blue",
main = "Rank Transformed")
# -------fit model FPReg RANK----------
reg_data = list(x=reg_temp, N=nrow(reg_temp))
fit_reg = stan(
file="stan_models/bivariate_correlation_rank.stan",
data=reg_data,
iter=4000,
chains=4,
cores=4,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_rank_drop0s.rds"))
print("skip Prob.")
[1] "skip Prob."
skip_df = provo_df %>% filter(metric == "skip") %>%
spread(measure, value) %>%
filter(eyetr_value > 0, motr_value > 0) %>%
mutate(eyetr_value = pmax(eyetr_value, 1e-5),
motr_value = pmax(motr_value, 1e-5))
print(cor.test(skip_df$eyetr_value, skip_df$motr_value)$estimate)
cor
0.7945
# View(reg_df)
skip_df %>%
gather(measure, value, 12:13) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
skip_temp <- skip_df[c("eyetr_value", "motr_value")] %>% data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(skip_temp, pch = 16, col = "blue",
main = "Not Log-Transformed")

# -------fit model skip ----------
skip_data = list(x=skip_temp, N=nrow(skip_temp))
fit_skip = stan(
file="stan_models/bivariate_normal_reg.stan",
data=skip_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_skip@stanmodel@dso <- new("cxxdso")
saveRDS(fit_skip, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_skip_cor_drop0s.rds"))
fit_gd = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds")
fit_gpt = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds")
fit_td = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds")
fit_reg = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_drop0s.rds")
fit_reg_rank = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_rank_drop0s.rds")
fit_skip = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_skip_cor_drop0s.rds")
# models for drop 0s
# fit_gd = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds")
# fit_gpt = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds")
# fit_td = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds")
# fit_reg = readRDS("./bayesian_models/bayesian_models_correlation/ranked_motr_eyetr_FPReg_cor.rds")
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
print(fit_gd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 234.30 0.01 0.90 232.53 233.69 234.29 234.91 236.06 6945 1
mu[2] 371.77 0.02 1.74 368.30 370.63 371.77 372.91 375.24 6640 1
sigma[1] 37.80 0.01 0.81 36.24 37.26 37.79 38.34 39.42 5283 1
sigma[2] 71.83 0.02 1.46 69.03 70.82 71.83 72.82 74.71 5227 1
nu 4.46 0.00 0.30 3.92 4.25 4.45 4.65 5.08 5469 1
rho 0.51 0.00 0.02 0.48 0.50 0.51 0.52 0.54 6947 1
cov[1,1] 1429.34 0.84 61.16 1313.63 1388.16 1427.81 1469.75 1553.95 5276 1
cov[1,2] 1391.14 1.15 78.47 1239.24 1339.15 1390.35 1441.79 1551.58 4667 1
cov[2,1] 1391.14 1.15 78.47 1239.24 1339.15 1390.35 1441.79 1551.58 4667 1
cov[2,2] 5161.37 2.91 210.40 4765.32 5015.23 5159.80 5302.57 5580.95 5231 1
x_rand[1] 235.01 0.55 49.34 138.86 206.52 234.61 262.42 336.83 8089 1
x_rand[2] 373.62 1.07 95.15 182.83 319.23 372.21 425.30 567.12 7980 1
attempt 0.00 0.00 0.05 0.00 0.00 0.00 0.00 0.00 8050 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ -25082.82 0.03 1.80 -25087.41 -25083.73 -25082.46 -25081.52 -25080.40 3875 1
Samples were drawn using NUTS(diag_e) at Tue Feb 6 00:04:08 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
print(fit_gpt)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 306.99 0.02 1.71 303.61 305.9 306.97 308.14 310.35 8255 1
mu[2] 425.10 0.03 2.96 419.39 423.0 425.10 427.11 430.79 8294 1
sigma[1] 67.11 0.02 1.47 64.27 66.1 67.10 68.10 70.03 7296 1
sigma[2] 116.24 0.03 2.64 111.16 114.5 116.21 118.01 121.46 7232 1
nu 2.26 0.00 0.09 2.08 2.2 2.26 2.32 2.45 7418 1
rho 0.42 0.00 0.02 0.38 0.4 0.42 0.43 0.45 8786 1
cov[1,1] 4505.28 2.31 197.26 4130.64 4369.6 4501.91 4637.37 4904.27 7307 1
cov[1,2] 3248.81 2.51 213.71 2842.87 3101.4 3244.96 3391.94 3668.78 7277 1
cov[2,1] 3248.81 2.51 213.71 2842.87 3101.4 3244.96 3391.94 3668.78 7277 1
cov[2,2] 13517.55 7.22 613.53 12357.23 13097.8 13505.59 13925.78 14752.13 7226 1
x_rand[1] 318.77 1.49 134.42 121.89 258.4 309.38 363.21 564.06 8092 1
x_rand[2] 451.19 3.26 294.27 111.69 344.8 430.62 522.20 876.86 8131 1
attempt 0.04 0.00 0.21 0.00 0.0 0.00 0.00 1.00 8093 1
max_attempts 10.00 NaN 0.00 10.00 10.0 10.00 10.00 10.00 NaN NaN
lp__ -29010.67 0.03 1.76 -29015.10 -29011.6 -29010.35 -29009.40 -29008.25 3994 1
Samples were drawn using NUTS(diag_e) at Tue Feb 6 00:05:58 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
print(fit_td)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 266.87 0.02 1.28 264.39 266.01 266.86 267.75 269.33 5448 1
mu[2] 420.80 0.03 2.46 416.02 419.15 420.76 422.47 425.53 5573 1
sigma[1] 52.62 0.02 1.10 50.47 51.88 52.61 53.36 54.78 4500 1
sigma[2] 100.49 0.03 2.03 96.58 99.11 100.48 101.84 104.53 4579 1
nu 4.28 0.00 0.27 3.79 4.09 4.27 4.46 4.85 5361 1
rho 0.62 0.00 0.01 0.59 0.61 0.62 0.63 0.65 6752 1
cov[1,1] 2769.92 1.73 115.77 2547.56 2691.20 2768.16 2846.87 3000.64 4498 1
cov[1,2] 3278.82 2.57 164.70 2966.61 3164.38 3277.56 3386.73 3608.01 4100 1
cov[2,1] 3278.82 2.57 164.70 2966.61 3164.38 3277.56 3386.73 3608.01 4100 1
cov[2,2] 10102.99 6.04 408.74 9326.88 9822.79 10095.99 10371.05 10925.76 4584 1
x_rand[1] 268.11 0.79 69.98 127.37 228.67 268.19 306.65 407.71 7859 1
x_rand[2] 427.30 1.52 133.15 166.09 351.69 423.23 498.89 698.02 7666 1
attempt 0.01 0.00 0.09 0.00 0.00 0.00 0.00 0.00 8123 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ -26591.96 0.03 1.74 -26596.19 -26592.83 -26591.63 -26590.69 -26589.56 3343 1
Samples were drawn using NUTS(diag_e) at Tue Feb 6 00:07:59 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.--------------------------------------------"
print(fit_reg)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.14 0.00 0.00 0.13 0.14 0.14 0.14 0.14 8022 1
mu[2] 0.09 0.00 0.00 0.08 0.08 0.09 0.09 0.09 8135 1
sigma[1] 0.08 0.00 0.00 0.08 0.08 0.08 0.08 0.09 7142 1
sigma[2] 0.05 0.00 0.00 0.04 0.05 0.05 0.05 0.05 7221 1
nu 2.78 0.00 0.18 2.46 2.65 2.77 2.89 3.14 7451 1
rho 0.21 0.00 0.03 0.16 0.19 0.21 0.23 0.27 9921 1
cov[1,1] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.01 7143 1
cov[1,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 8463 1
cov[2,1] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 8463 1
cov[2,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 7208 1
x_rand[1] 0.17 0.00 0.13 0.02 0.10 0.15 0.21 0.42 7885 1
x_rand[2] 0.10 0.00 0.07 0.01 0.06 0.09 0.12 0.25 7935 1
attempt 0.17 0.01 0.46 0.00 0.00 0.00 0.00 1.00 7711 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 4545.35 0.03 1.75 4541.07 4544.43 4545.68 4546.62 4547.74 3653 1
Samples were drawn using NUTS(diag_e) at Tue Feb 6 00:09:17 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob. RANK--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. RANK--------------------------------------------"
print(fit_reg_rank)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 1374.90 0.18 18.98 1337.48 1362.16 1374.73 1387.9 1411.91 11231 1
mu[2] 1804.27 0.11 11.31 1782.23 1796.66 1804.43 1811.9 1826.26 10240 1
sigma[1] 696.99 0.12 12.87 672.39 688.36 696.94 705.4 723.03 10941 1
sigma[2] 418.96 0.08 7.84 403.87 413.54 418.83 424.2 434.92 10853 1
nu 102.55 0.23 23.98 63.02 85.64 100.14 116.5 157.44 10504 1
rho 0.19 0.00 0.03 0.14 0.17 0.19 0.2 0.24 11138 1
cov[1,1] 485954.71 172.11 17956.82 452113.94 473835.62 485723.58 497595.5 522770.76 10885 1
cov[1,2] 54509.75 75.79 7861.98 39206.85 49139.03 54379.02 59723.2 70306.93 10762 1
cov[2,1] 54509.75 75.79 7861.98 39206.85 49139.03 54379.02 59723.2 70306.93 10762 1
cov[2,2] 175589.65 63.18 6576.69 163113.47 171011.52 175420.06 179976.5 189159.61 10834 1
x_rand[1] 1420.17 7.48 659.95 217.73 942.20 1404.35 1864.0 2767.59 7778 1
x_rand[2] 1804.04 4.94 427.24 964.46 1521.76 1803.44 2090.0 2641.59 7493 1
attempt 0.03 0.00 0.18 0.00 0.00 0.00 0.0 1.00 8072 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.0 10.00 NaN NaN
lp__ -20329.53 0.03 1.75 -20333.76 -20330.49 -20329.20 -20328.2 -20327.15 4066 1
Samples were drawn using NUTS(diag_e) at Tue Feb 6 00:12:53 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- Skip Prob.--------------------------------------------')
[1] "---------------------------- Skip Prob.--------------------------------------------"
print(fit_skip)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.44 0.00 0.00 0.43 0.44 0.44 0.44 0.45 5294 1
mu[2] 0.46 0.00 0.01 0.45 0.45 0.46 0.46 0.47 5320 1
sigma[1] 0.22 0.00 0.00 0.22 0.22 0.22 0.23 0.23 4893 1
sigma[2] 0.25 0.00 0.00 0.24 0.25 0.25 0.25 0.25 5030 1
nu 100.97 0.26 23.54 62.68 84.28 98.17 115.01 154.51 7911 1
rho 0.80 0.00 0.01 0.78 0.79 0.80 0.80 0.81 5412 1
cov[1,1] 0.05 0.00 0.00 0.05 0.05 0.05 0.05 0.05 4891 1
cov[1,2] 0.04 0.00 0.00 0.04 0.04 0.04 0.05 0.05 4075 1
cov[2,1] 0.04 0.00 0.00 0.04 0.04 0.04 0.05 0.05 4075 1
cov[2,2] 0.06 0.00 0.00 0.06 0.06 0.06 0.06 0.06 5025 1
x_rand[1] 0.46 0.00 0.20 0.09 0.32 0.46 0.60 0.89 7796 1
x_rand[2] 0.48 0.00 0.23 0.08 0.32 0.47 0.63 0.96 7592 1
attempt 0.05 0.00 0.21 0.00 0.00 0.00 0.00 1.00 7949 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 4253.99 0.03 1.75 4249.74 4253.06 4254.32 4255.27 4256.38 3625 1
Samples were drawn using NUTS(diag_e) at Sun Feb 25 01:27:44 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
# stan_trace(fit_gd, pars=c("rho", "mu", "sigma", "nu"))
# stan_dens(fit_gd, pars=c("rho", "mu", "sigma", "nu"), separate_chains = TRUE)
# stan_plot(fit_gd, pars=c("rho", "mu", "sigma", "nu"))
# Gaze Duration
stan_trace(fit_gd)
stan_dens(fit_gd, separate_chains = TRUE)
stan_plot(fit_gd)
# Go Past Time
stan_trace(fit_gpt)
stan_dens(fit_gpt, separate_chains = TRUE)
stan_plot(fit_gpt)
# Total Duration
stan_trace(fit_td)
stan_dens(fit_td, separate_chains = TRUE)
stan_plot(fit_td)
# FPReg
stan_trace(fit_reg)
stan_dens(fit_reg, separate_chains = TRUE)
stan_plot(fit_reg)
p1 <- stan_trace(fit_gd, pars = 'rho', inc_warmup = FALSE)
p2 <- stan_dens(fit_gd, pars = 'rho', separate_chains = TRUE)
p3 <- stan_trace(fit_gd, pars = 'mu[1]', inc_warmup = FALSE)
p4 <- stan_dens(fit_gd, pars = 'mu[1]', separate_chains = TRUE)
p5 <- stan_trace(fit_gd, pars = 'mu[2]', inc_warmup = FALSE)
p6 <- stan_dens(fit_gd, pars = 'mu[2]', separate_chains = TRUE)
p7 <- stan_trace(fit_gd, pars = 'sigma[1]', inc_warmup = FALSE)
p8 <- stan_dens(fit_gd, pars = 'sigma[1]', separate_chains = TRUE)
p9 <- stan_trace(fit_gd, pars = 'sigma[2]', inc_warmup = FALSE)
p10 <- stan_dens(fit_gd, pars = 'sigma[2]', separate_chains = TRUE)
p11 <- stan_trace(fit_gd, pars = 'nu', inc_warmup = FALSE)
p12 <- stan_dens(fit_gd, pars = 'nu', separate_chains = TRUE)
# Use grid.arrange() to arrange the plots
# grid.arrange(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, ncol=2, nrow=6)
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
rho_gd = as.numeric(extract(fit_gd, "rho")[[1]])
mean = mean(rho_gd)
crI = quantile(rho_gd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_gd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.5121
HPD: [0.4784, 0.5441]
crI: [0.4789, 0.5448]
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
rho_gpt = as.numeric(extract(fit_gpt, "rho")[[1]])
mean = mean(rho_gpt)
crI = quantile(rho_gpt, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_gpt), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.4163
HPD: [0.3793, 0.455]
crI: [0.378, 0.4539]
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
rho_td = as.numeric(extract(fit_td, "rho")[[1]])
mean = mean(rho_td)
crI = quantile(rho_td, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_td), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6197
HPD: [0.5915, 0.6471]
crI: [0.5912, 0.647]
print('---------------------------- First Pass Regression --------------------------------------------')
[1] "---------------------------- First Pass Regression --------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_reg = as.numeric(extract(fit_reg, "rho")[[1]])
mean = mean(rho_reg)
crI = quantile(rho_reg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_reg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.2139
HPD: [0.1561, 0.2715]
crI: [0.1554, 0.2711]
print('---------------------------- First Pass Regression RANK--------------------------------------------')
[1] "---------------------------- First Pass Regression RANK--------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_reg = as.numeric(extract(fit_reg_rank, "rho")[[1]])
mean = mean(rho_reg)
crI = quantile(rho_reg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_reg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
Mean: 0.1866
HPD: [0.1359, 0.2356]
crI: [0.1367, 0.2367]
print('---------------------------- Skip --------------------------------------------')
[1] "---------------------------- Skip --------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_skip = as.numeric(extract(fit_skip, "rho")[[1]])
mean = mean(rho_skip)
crI = quantile(rho_skip, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_skip), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.7975
HPD: [0.7823, 0.8112]
crI: [0.7827, 0.8117]
print('---------------------------- Gaze Duration--------------------------------------------')
gd_rand <- extract(fit_gd, "x_rand")[[1]]
# x_rand_filtered <- x_rand[apply(x_rand, 1, function(x) all(x > 0)),]
# x_rand_filtered
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 400), ylim=c(0, 700), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(gd_rand[,1], gd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(gd_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(gd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(gd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- Go Past Time--------------------------------------------')
gpt_rand <- extract(fit_gpt, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "Go Past Time") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(gpt_rand[,1], gpt_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(gpt_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(gpt_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(gpt_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- Total Duration--------------------------------------------')
td_rand <- extract(fit_td, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "Total Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(td_rand[,1], td_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(td_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(td_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(td_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression --------------------------------------------')
reg_rand <- extract(fit_reg, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(reg_rand[,1], reg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(reg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(reg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- Skip --------------------------------------------')
skip_rand <- extract(fit_skip, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "Skip") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(skip_rand[,1], skip_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(skip_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(skip_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(skip_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
model motr eyetr FPReg correlation (eyetr < 0.3)
print("First Pass Regression Prob. all and < 0.3")
[1] "First Pass Regression Prob. all and < 0.3"
reg_df_all = provo_df %>% filter(metric == "FPReg") %>%
spread(measure, value) %>%
# filter(eyetr_value > 0, motr_value > 0) %>%
mutate(eyetr_value = pmax(eyetr_value, 1e-5),
motr_value = pmax(motr_value, 1e-5))
reg_df_low_drop0 = provo_df %>% filter(metric == "FPReg") %>%
spread(measure, value) %>%
filter(eyetr_value > 0, motr_value > 0) %>%
mutate(eyetr_value = pmax(eyetr_value, 1e-5),
motr_value = pmax(motr_value, 1e-5)) %>%
filter(eyetr_value < 0.3)
reg_df_low = provo_df %>% filter(metric == "FPReg") %>%
spread(measure, value) %>%
# filter(eyetr_value > 0, motr_value > 0) %>%
mutate(eyetr_value = pmax(eyetr_value, 1e-5),
motr_value = pmax(motr_value, 1e-5)) %>%
filter(eyetr_value < 0.3)
# mutate(eyetr_value = exp(eyetr_value),
# motr_value = exp(motr_value)
# )
# View(reg_df)
print(cor.test(reg_df_all$eyetr_value, reg_df_all$motr_value)$estimate)
cor
0.3024
print(cor.test(reg_df_all$eyetr_value, reg_df_all$motr_value)$p.value)
[1] 0.000000000000000000000000000000000000000000000000000000915
print(cor.test(reg_df_low$eyetr_value, reg_df_low$motr_value)$estimate)
cor
0.1071
print(cor.test(reg_df_low$eyetr_value, reg_df_low$motr_value)$p.value)
[1] 0.000000334
print(cor.test(reg_df_low_drop0$eyetr_value, reg_df_low_drop0$motr_value)$estimate)
cor
0.08719
print(cor.test(reg_df_low_drop0$eyetr_value, reg_df_low_drop0$motr_value)$p.value)
[1] 0.002145
# View(reg_df)
reg_df_low %>%
gather(measure, value, 12:13) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
reg_temp_all <- reg_df_all[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_low <- reg_df_low[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_low_drop0 <- reg_df_low_drop0[c("eyetr_value", "motr_value")] %>% data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(reg_temp_low, pch = 16, col = "blue",
main = "Not Log-Transformed")

# -------fit model FPReg < 0.3 ----------
reg_data = list(x=reg_temp_all, N=nrow(reg_temp_all))
fit_reg = stan(
# file="stan_models/bivariate_beta_correlation_reg.stan",
file = "stan_models/bivariate_normal_reg.stan",
data=reg_data,
iter=4000,
chains=4,
cores=4,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_all_data_drop0s.rds"))
model motr eyetr FPReg correlation (eyetr >= 0.3)
print("First Pass Regression Prob. >= 0.3")
[1] "First Pass Regression Prob. >= 0.3"
reg_df_high_drop0 = provo_df %>% filter(metric == "FPReg") %>%
spread(measure, value) %>%
filter(eyetr_value > 0, motr_value > 0) %>%
mutate(eyetr_value = pmax(eyetr_value, 1e-5),
motr_value = pmax(motr_value, 1e-5)) %>%
filter(eyetr_value >= 0.3)
reg_df_high = provo_df %>% filter(metric == "FPReg") %>%
spread(measure, value) %>%
# filter(eyetr_value > 0, motr_value > 0) %>%
mutate(eyetr_value = pmax(eyetr_value, 1e-5),
motr_value = pmax(motr_value, 1e-5)) %>%
filter(eyetr_value >= 0.3)
# mutate(eyetr_value = exp(eyetr_value),
# motr_value = exp(motr_value)
# )
# View(reg_df)
print(cor.test(reg_df_high$eyetr_value, reg_df_high$motr_value)$estimate)
cor
0.4202
print(cor.test(reg_df_high$eyetr_value, reg_df_high$motr_value)$p.value)
[1] 0.0000000000002819
print(cor.test(reg_df_high_drop0$eyetr_value, reg_df_high_drop0$motr_value)$estimate)
cor
0.4904
print(cor.test(reg_df_high_drop0$eyetr_value, reg_df_high_drop0$motr_value)$p.value)
[1] 0.0000000000012
# View(reg_df)
reg_df_high %>%
gather(measure, value, 12:13) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
reg_temp_high <- reg_df_high[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_high_drop0 <- reg_df_high_drop0[c("eyetr_value", "motr_value")] %>% data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 3))

# Plot the first data matrix td_temp
plot(reg_temp_all, pch = 16, col = "blue",
main = "FPReg not logged all data")
plot(reg_temp_low, pch = 16, col = "blue",
main = "FPReg not logged eyetr < 0.3 ")
plot(reg_temp_high, pch = 16, col = "blue",
main = "FPReg not logged eyetr >= 0.3")

# -------fit model FPReg >= 0.3 ----------
reg_data = list(x=reg_temp_high_drop0, N=nrow(reg_temp_high_drop0))
fit_reg = stan(
# file="stan_models/bivariate_beta_correlation_reg.stan",
file = "stan_models/bivariate_normal_reg.stan",
data=reg_data,
iter=4000,
chains=4,
cores=4,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0(".//bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_03-1_drop0s.rds"))
fit_mreg_all = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_all_data.rds")
fit_mreg_all_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_all_data_drop0s.rds")
fit_mreg_low = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_00-03.rds")
fit_mreg_low_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_00-03_drop0s.rds")
fit_mreg_high = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_03-1.rds")
fit_mreg_high_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_03-1_drop0s.rds")
print('---------------------------- First Pass Regression Prob. all data --------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. all data --------------------------------------------"
print(fit_mreg_all)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.12 0.00 0.00 0.12 0.12 0.12 0.13 0.13 5811 1
mu[2] 0.03 0.00 0.00 0.02 0.03 0.03 0.03 0.03 3384 1
sigma[1] 0.08 0.00 0.00 0.07 0.07 0.08 0.08 0.08 3694 1
sigma[2] 0.05 0.00 0.00 0.05 0.05 0.05 0.05 0.06 3040 1
nu 2.42 0.00 0.14 2.16 2.33 2.42 2.52 2.71 3250 1
rho 0.16 0.00 0.02 0.11 0.14 0.16 0.17 0.20 8176 1
cov[1,1] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.01 3693 1
cov[1,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6348 1
cov[2,1] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6348 1
cov[2,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3053 1
x_rand[1] 0.16 0.00 0.12 0.02 0.09 0.14 0.20 0.40 7811 1
x_rand[2] 0.07 0.00 0.08 0.00 0.03 0.05 0.09 0.25 7966 1
attempt 0.63 0.01 1.03 0.00 0.00 0.00 1.00 3.00 7919 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 7450.58 0.03 1.78 7446.22 7449.65 7450.92 7451.89 7452.98 3519 1
Samples were drawn using NUTS(diag_e) at Sat Aug 5 23:08:09 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob. all data no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. all data no 0s--------------------------------------------"
print(fit_mreg_all_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.15 0.00 0.00 0.14 0.15 0.15 0.15 0.16 8507 1
mu[2] 0.14 0.00 0.00 0.13 0.14 0.14 0.14 0.14 7923 1
sigma[1] 0.09 0.00 0.00 0.08 0.08 0.09 0.09 0.09 7186 1
sigma[2] 0.06 0.00 0.00 0.06 0.06 0.06 0.06 0.06 6227 1
nu 2.78 0.00 0.23 2.37 2.62 2.77 2.93 3.26 7008 1
rho 0.18 0.00 0.04 0.11 0.16 0.18 0.21 0.26 9833 1
cov[1,1] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.01 7173 1
cov[1,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 8599 1
cov[2,1] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 8599 1
cov[2,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 6234 1
x_rand[1] 0.18 0.00 0.13 0.02 0.10 0.16 0.22 0.43 7699 1
x_rand[2] 0.15 0.00 0.08 0.03 0.10 0.14 0.18 0.34 8175 1
attempt 0.16 0.00 0.43 0.00 0.00 0.00 0.00 1.00 7917 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 2566.44 0.03 1.75 2562.18 2565.53 2566.76 2567.72 2568.88 3487 1
Samples were drawn using NUTS(diag_e) at Sat Aug 5 23:18:11 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------"
print(fit_mreg_low)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.12 0.00 0.00 0.11 0.12 0.12 0.12 0.12 8566 1
mu[2] 0.03 0.00 0.00 0.03 0.03 0.03 0.04 0.04 4981 1
sigma[1] 0.06 0.00 0.00 0.06 0.06 0.06 0.06 0.07 7280 1
sigma[2] 0.06 0.00 0.00 0.06 0.06 0.06 0.06 0.07 4552 1
nu 5.54 0.01 0.51 4.62 5.19 5.51 5.86 6.62 4637 1
rho 0.10 0.00 0.02 0.06 0.09 0.10 0.12 0.15 8596 1
cov[1,1] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 7299 1
cov[1,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 8259 1
cov[2,1] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 8259 1
cov[2,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 4571 1
x_rand[1] 0.13 0.00 0.07 0.02 0.08 0.12 0.17 0.28 8277 1
x_rand[2] 0.07 0.00 0.06 0.00 0.03 0.06 0.10 0.21 7280 1
attempt 0.53 0.01 0.90 0.00 0.00 0.00 1.00 3.00 8006 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 7794.82 0.03 1.78 7790.50 7793.88 7795.16 7796.13 7797.26 3232 1
Samples were drawn using NUTS(diag_e) at Sat Aug 5 20:52:03 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.< 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.< 0.3 no 0s--------------------------------------------"
print(fit_mreg_low_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.13 0.00 0.00 0.13 0.13 0.13 0.13 0.14 10534 1
mu[2] 0.13 0.00 0.00 0.13 0.13 0.13 0.14 0.14 8839 1
sigma[1] 0.06 0.00 0.00 0.06 0.06 0.06 0.06 0.07 8534 1
sigma[2] 0.06 0.00 0.00 0.06 0.06 0.06 0.07 0.07 7122 1
nu 6.50 0.01 0.96 4.90 5.83 6.40 7.06 8.73 6790 1
rho 0.07 0.00 0.04 0.00 0.05 0.07 0.10 0.15 10356 1
cov[1,1] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 8526 1
cov[1,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 10435 1
cov[2,1] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 10435 1
cov[2,2] 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 7123 1
x_rand[1] 0.14 0.00 0.07 0.02 0.09 0.13 0.18 0.28 8031 1
x_rand[2] 0.14 0.00 0.07 0.02 0.10 0.14 0.18 0.29 8006 1
attempt 0.08 0.00 0.30 0.00 0.00 0.00 0.00 1.00 7642 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 2737.21 0.03 1.76 2732.81 2736.27 2737.56 2738.50 2739.62 3992 1
Samples were drawn using NUTS(diag_e) at Sat Aug 5 20:30:02 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------"
print(fit_mreg_high)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.45 0.00 0.01 0.44 0.45 0.45 0.46 0.47 5045 1
mu[2] 0.15 0.00 0.01 0.13 0.15 0.15 0.16 0.18 4628 1
sigma[1] 0.11 0.00 0.01 0.10 0.11 0.11 0.12 0.12 5622 1
sigma[2] 0.15 0.00 0.01 0.13 0.15 0.15 0.16 0.17 4499 1
nu 25.71 0.18 12.83 9.59 16.53 22.89 31.70 58.03 5109 1
rho 0.41 0.00 0.06 0.30 0.37 0.41 0.45 0.51 7137 1
cov[1,1] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.02 5625 1
cov[1,2] 0.01 0.00 0.00 0.00 0.01 0.01 0.01 0.01 4842 1
cov[2,1] 0.01 0.00 0.00 0.00 0.01 0.01 0.01 0.01 4842 1
cov[2,2] 0.02 0.00 0.00 0.02 0.02 0.02 0.03 0.03 4553 1
x_rand[1] 0.47 0.00 0.11 0.25 0.39 0.47 0.54 0.70 7964 1
x_rand[2] 0.20 0.00 0.13 0.01 0.10 0.19 0.28 0.49 7829 1
attempt 0.19 0.01 0.47 0.00 0.00 0.00 0.00 1.00 7881 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 579.26 0.03 1.75 575.10 578.35 579.56 580.56 581.68 3529 1
Samples were drawn using NUTS(diag_e) at Sat Aug 5 22:25:38 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.>= 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.>= 0.3 no 0s--------------------------------------------"
print(fit_mreg_high_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.48 0.00 0.01 0.46 0.48 0.48 0.49 0.51 6409 1
mu[2] 0.27 0.00 0.01 0.25 0.26 0.27 0.28 0.30 6397 1
sigma[1] 0.12 0.00 0.01 0.11 0.12 0.12 0.13 0.14 6555 1
sigma[2] 0.16 0.00 0.01 0.14 0.15 0.16 0.17 0.18 6281 1
nu 32.85 0.16 15.27 11.84 21.65 30.12 40.80 69.54 8953 1
rho 0.51 0.00 0.07 0.37 0.47 0.52 0.56 0.64 6986 1
cov[1,1] 0.02 0.00 0.00 0.01 0.01 0.02 0.02 0.02 6491 1
cov[1,2] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.02 5145 1
cov[2,1] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.02 5145 1
cov[2,2] 0.03 0.00 0.00 0.02 0.02 0.03 0.03 0.03 6242 1
x_rand[1] 0.49 0.00 0.13 0.25 0.41 0.49 0.57 0.74 8129 1
x_rand[2] 0.29 0.00 0.15 0.04 0.18 0.28 0.38 0.60 7467 1
attempt 0.06 0.00 0.24 0.00 0.00 0.00 0.00 1.00 7913 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 300.28 0.03 1.75 296.05 299.35 300.60 301.58 302.70 3555 1
Samples were drawn using NUTS(diag_e) at Sat Aug 5 22:31:08 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
# # FPReg all data
# stan_trace(fit_mreg_all)
# stan_dens(fit_mreg_all, separate_chains = TRUE)
# stan_plot(fit_mreg_all)
# stan_trace(fit_mreg_all_drop0)
# stan_dens(fit_mreg_all_drop0, separate_chains = TRUE)
# stan_plot(fit_mreg_all_drop0)
# # FPReg < 0.3
# stan_trace(fit_mreg_low)
# stan_dens(fit_mreg_low, separate_chains = TRUE)
# stan_plot(fit_mreg_low)
#
# stan_trace(fit_mreg_low_drop0)
# stan_dens(fit_mreg_low_drop0, separate_chains = TRUE)
# stan_plot(fit_mreg_low_drop0)
# FPReg > 0.3
stan_trace(fit_mreg_high)
'pars' not specified. Showing first 10 parameters by default.

stan_dens(fit_mreg_high, separate_chains = TRUE)
'pars' not specified. Showing first 10 parameters by default.

stan_plot(fit_mreg_high)
'pars' not specified. Showing first 10 parameters by default.
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

stan_trace(fit_mreg_high_drop0)
'pars' not specified. Showing first 10 parameters by default.

stan_dens(fit_mreg_high_drop0, separate_chains = TRUE)
'pars' not specified. Showing first 10 parameters by default.

stan_plot(fit_mreg_high_drop0)
'pars' not specified. Showing first 10 parameters by default.
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

print('---------------------------- First Pass Regression all data--------------------------------------------')
[1] "---------------------------- First Pass Regression all data--------------------------------------------"
rho_mreg_all = as.numeric(extract(fit_mreg_all, "rho")[[1]])
mean = mean(rho_mreg_all)
crI = quantile(rho_mreg_all, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_all), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.1574
HPD: [0.1139, 0.2017]
crI: [0.1134, 0.2014]
print('---------------------------- First Pass Regression all data no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression all data no 0s--------------------------------------------"
rho_mreg_all_drop0 = as.numeric(extract(fit_mreg_all_drop0, "rho")[[1]])
mean = mean(rho_mreg_all_drop0)
crI = quantile(rho_mreg_all_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_all_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.1843
HPD: [0.1106, 0.2573]
crI: [0.1114, 0.2581]
print('---------------------------- First Pass Regression < 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression < 0.3--------------------------------------------"
rho_mreg_low = as.numeric(extract(fit_mreg_low, "rho")[[1]])
mean = mean(rho_mreg_low)
crI = quantile(rho_mreg_low, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_low), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.103
HPD: [0.05775, 0.1468]
crI: [0.05805, 0.1475]
print('---------------------------- First Pass Regression < 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression < 0.3 no 0s--------------------------------------------"
rho_mreg_low_drop0 = as.numeric(extract(fit_mreg_low_drop0, "rho")[[1]])
mean = mean(rho_mreg_low_drop0)
crI = quantile(rho_mreg_low_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_low_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.07362
HPD: [-0.000616, 0.1514]
crI: [-0.003759, 0.1491]
print('---------------------------- First Pass Regression >= 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression >= 0.3--------------------------------------------"
rho_mreg_high = as.numeric(extract(fit_mreg_high, "rho")[[1]])
mean = mean(rho_mreg_high)
crI = quantile(rho_mreg_high, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_high), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.4102
HPD: [0.3001, 0.5155]
crI: [0.2992, 0.5146]
print('---------------------------- First Pass Regression >= 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression >= 0.3 no 0s--------------------------------------------"
rho_mreg_high_drop0 = as.numeric(extract(fit_mreg_high_drop0, "rho")[[1]])
mean = mean(rho_mreg_high_drop0)
crI = quantile(rho_mreg_high_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_high_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.514
HPD: [0.3797, 0.6456]
crI: [0.3728, 0.6412]
print('---------------------------- First Pass Regression all data --------------------------------------------')
mallreg_rand <- extract(fit_mreg_all, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mallreg_rand[,1], mallreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_all, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mallreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mallreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression all data no 0s--------------------------------------------')
mallreg_rand_drop0 <- extract(fit_mreg_all_drop0, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mallreg_rand_drop0[,1], mallreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_all, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mallreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mallreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression < 0.3 --------------------------------------------')
mlowreg_rand <- extract(fit_mreg_low, "x_rand")[[1]]
print(mlowreg_rand)
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mlowreg_rand[,1], mlowreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_low, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mlowreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlowreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression < 0.3 no 0s --------------------------------------------')
mlowreg_rand_drop0 <- extract(fit_mreg_low_drop0, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mlowreg_rand_drop0[,1], mlowreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_low_drop0, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mlowreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlowreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression >= 0.3 --------------------------------------------')
mhighreg_rand_samples <- extract(fit_mreg_high, "x_rand")[[1]]
# print(mhighreg_rand_samples)
selected_indices <- sample(1:nrow(mhighreg_rand_samples), 900)
mhighreg_rand <- mhighreg_rand_samples[selected_indices, ]
# mhighreg_rand <- extract(fit_mreg_high, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mhighreg_rand[,1], mhighreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_high, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mhighreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mhighreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
# print('---------------------------- First Pass Regression >= 0.3 no 0s --------------------------------------------')
mhighreg_rand_drop0_samples <- extract(fit_mreg_high_drop0, "x_rand")[[1]]
selected_indices <- sample(1:nrow(mhighreg_rand_drop0_samples), 900)
mhighreg_rand_drop0 <- mhighreg_rand_drop0_samples[selected_indices, ]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mhighreg_rand_drop0[,1], mhighreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_high_drop0, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mhighreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mhighreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
model eye tracking to eye tracking correlation
print("Gaze Duration")
[1] "Gaze Duration"
# View(provo_eyetr_grouped_df)
egd_df = provo_eyetr_grouped_df %>% filter(metric == "gaze_duration") %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
filter(text_id != 18) %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value_1 = pmax(value_1, 1),
eyetr_value_2 = pmax(value_2, 1)
)
print(cor.test(egd_df$eyetr_value_1, egd_df$eyetr_value_2)$estimate)
cor
0.767
# View(egd_df)
egd_df %>%
gather(measure, value, 5:6) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
egd_temp <- egd_df[c("eyetr_value_1", "eyetr_value_2")] %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(egd_temp, pch = 16, col = "blue",
main = "Not Log-Transformed")

egd_data = list(x=egd_temp, N=nrow(egd_temp))
fit_egd = stan(
file="stan_models/bivariate_correlation.stan",
data=egd_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_egd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_egd, file = paste0("./bayesian_models/bayesian_models_correlation/cor_bivariate/eyetr_eyetr_gaze_duration_cor.rds"))
print("Go Past Time")
[1] "Go Past Time"
egpt_df = provo_eyetr_grouped_df %>% filter(metric == "go_past_time") %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
filter(text_id != 18) %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value_1 = pmax(value_1, 1),
eyetr_value_2 = pmax(value_2, 1)
)
print(cor.test(egpt_df$eyetr_value_1, egpt_df$eyetr_value_2)$estimate)
cor
0.5582
# View(egd_df)
egpt_df %>%
gather(measure, value, 5:6) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
egpt_temp <- egpt_df[c("eyetr_value_1", "eyetr_value_2")] %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(egpt_temp, pch = 16, col = "blue",
main = "Not Log-Transformed")

egpt_data = list(x=egpt_temp, N=nrow(egpt_temp))
fit_egpt = stan(
file="stan_models/bivariate_correlation.stan",
data=egpt_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_egpt@stanmodel@dso <- new("cxxdso")
saveRDS(fit_egpt, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_go_past_time_cor.rds"))
print("Total Duration")
[1] "Total Duration"
etd_df = provo_eyetr_grouped_df %>% filter(metric == "total_duration") %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
filter(text_id != 18) %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value_1 = pmax(value_1, 1),
eyetr_value_2 = pmax(value_2, 1)
)
print(cor.test(etd_df$eyetr_value_1, etd_df$eyetr_value_2)$estimate)
cor
0.8341
# View(egd_df)
etd_df %>%
gather(measure, value, 5:6) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
etd_temp <- etd_df[c("eyetr_value_1", "eyetr_value_2")] %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(etd_temp, pch = 16, col = "blue",
main = "Total Duration Not Log-Transformed")

etd_data = list(x=etd_temp, N=nrow(etd_temp))
fit_etd = stan(
file="stan_models/bivariate_correlation.stan",
data=etd_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
# verbose = FALSE
)
# Save the model
fit_etd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_etd, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_total_duration_cor.rds"))
print("Fisrt Pass Regression Prob.")
[1] "Fisrt Pass Regression Prob."
ereg_df = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value)) %>%
# filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
filter(text_id != 18) %>%
spread(measure, value) %>%
# ==== for normal data drop0s ====
# filter(value_1 > 0, value_2 > 0) %>%
# mutate(eyetr_value_1 = pmax(value_1, 1e-5),
# eyetr_value_2 = pmax(value_2, 1e-5)
# )
# ==== for ranking the data drop0s ====
mutate(
eyetr_value_1 = ifelse(value_1 > 0, rank(value_1), NA),
eyetr_value_2 = ifelse(value_2 > 0, rank(value_2), NA)
) %>%
drop_na()
# ==== for ranking the data w/ 0s ====
# mutate(
# eyetr_value_1 = rank(value_1, ties.method = "average"),
# eyetr_value_2 = rank(value_2, ties.method = "average")
# )
print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$estimate)
cor
0.5809
# View(egd_df)
ereg_df %>%
gather(measure, value, 5:6) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
ereg_temp <- ereg_df[c("eyetr_value_1", "eyetr_value_2")] %>%
drop_na() %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(ereg_temp, pch = 16, col = "blue",
main = "FPReg Not Log-Transformed")

# -------fit model FPReg ----------
# View(ereg_temp)
ereg_data = list(x=ereg_temp, N=nrow(ereg_temp))
fit_ereg = stan(
file="stan_models/bivariate_correlation_rank.stan",
data=ereg_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_ereg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_ereg, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_rank_drop0s.rds"))
print("Skip Prob.")
[1] "Skip Prob."
eskip_df = provo_eyetr_grouped_df %>% filter(metric == "skip") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value)) %>%
# filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
filter(text_id != 18) %>%
spread(measure, value)
# ==== for normal data drop0s ====
# filter(value_1 > 0, value_2 > 0) %>%
# mutate(eyetr_value_1 = pmax(value_1, 1e-5),
# eyetr_value_2 = pmax(value_2, 1e-5)
# )
# ==== for ranking the data drop0s ====
# mutate(
# eyetr_value_1 = ifelse(value_1 > 0, rank(value_1), NA),
# eyetr_value_2 = ifelse(value_2 > 0, rank(value_2), NA)
# ) %>%
# drop_na()
# ==== for ranking the data w/ 0s ====
# mutate(
# eyetr_value_1 = rank(value_1, ties.method = "average"),
# eyetr_value_2 = rank(value_2, ties.method = "average")
# )
print(cor.test(eskip_df$value_1, eskip_df$value_2)$estimate)
cor
0.9073
eskip_df %>%
gather(measure, value, 5:6) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
eskip_temp <- eskip_df[c("value_1", "value_2")] %>%
drop_na() %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(eskip_temp, pch = 16, col = "blue",
main = "Skip Not Log-Transformed")

# -------fit model Skip ----------
# View(ereg_temp)
eskip_data = list(x=eskip_temp, N=nrow(eskip_temp))
fit_eskip = stan(
file="stan_models/bivariate_normal_reg.stan",
data=eskip_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_eskip@stanmodel@dso <- new("cxxdso")
saveRDS(fit_eskip, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_skip_cor_drop0s.rds"))
fit_egd = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_gaze_duration_cor_drop0s.rds")
fit_egpt = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_go_past_time_cor_drop0s.rds")
fit_etd = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_total_duration_cor_drop0s.rds")
fit_ereg = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_drop0s.rds")
fit_eskip = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_skip_cor_drop0s.rds")
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
print(fit_egd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 234.21 0.01 1.00 232.27 233.54 234.19 234.87 236.20 4635 1
mu[2] 236.90 0.01 0.97 235.02 236.24 236.90 237.54 238.79 4910 1
sigma[1] 41.69 0.02 0.91 39.91 41.08 41.68 42.29 43.51 3619 1
sigma[2] 40.43 0.01 0.85 38.80 39.85 40.42 41.00 42.11 3582 1
nu 4.79 0.01 0.34 4.18 4.55 4.77 5.01 5.49 4490 1
rho 0.75 0.00 0.01 0.73 0.74 0.75 0.75 0.77 5064 1
cov[1,1] 1738.83 1.26 75.69 1593.04 1687.35 1737.16 1788.84 1892.83 3618 1
cov[1,2] 1261.40 1.07 60.61 1144.60 1219.78 1259.97 1301.33 1383.64 3231 1
cov[2,1] 1261.40 1.07 60.61 1144.60 1219.78 1259.97 1301.33 1383.64 3231 1
cov[2,2] 1635.31 1.15 68.73 1505.18 1588.13 1633.89 1680.99 1772.85 3581 1
x_rand[1] 235.04 0.60 53.55 126.81 204.21 234.45 265.21 343.46 8071 1
x_rand[2] 238.08 0.58 52.25 134.49 207.68 237.12 267.21 343.68 8199 1
attempt 0.00 0.00 0.06 0.00 0.00 0.00 0.00 0.00 7607 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ -22639.73 0.03 1.75 -22644.12 -22640.68 -22639.40 -22638.44 -22637.35 3653 1
Samples were drawn using NUTS(diag_e) at Mon Feb 5 23:34:23 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
print(fit_egpt)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 303.70 0.03 2.02 299.63 302.37 303.70 305.04 307.61 6230 1
mu[2] 302.11 0.02 1.80 298.65 300.89 302.10 303.33 305.69 6262 1
sigma[1] 77.62 0.03 1.77 74.18 76.42 77.61 78.81 81.07 4594 1
sigma[2] 68.55 0.02 1.51 65.64 67.52 68.54 69.56 71.58 4950 1
nu 2.33 0.00 0.10 2.13 2.25 2.32 2.40 2.53 5695 1
rho 0.63 0.00 0.01 0.60 0.62 0.63 0.64 0.66 7305 1
cov[1,1] 6028.02 4.05 274.38 5502.89 5840.25 6022.79 6211.77 6572.65 4595 1
cov[1,2] 3372.29 2.65 178.45 3030.75 3248.64 3367.12 3492.40 3732.72 4544 1
cov[2,1] 3372.29 2.65 178.45 3030.75 3248.64 3367.12 3492.40 3732.72 4544 1
cov[2,2] 4701.89 2.95 207.63 4308.25 4559.35 4698.02 4838.38 5123.15 4963 1
x_rand[1] 316.81 1.63 144.61 99.38 247.09 305.30 366.85 597.63 7836 1
x_rand[2] 312.58 1.38 123.98 111.40 252.31 305.23 357.38 569.45 8117 1
attempt 0.03 0.00 0.18 0.00 0.00 0.00 0.00 1.00 7784 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ -26967.65 0.03 1.74 -26971.89 -26968.58 -26967.31 -26966.37 -26965.23 3624 1
Samples were drawn using NUTS(diag_e) at Mon Feb 5 23:38:33 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
print(fit_etd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 272.77 0.02 1.40 270.02 271.83 272.77 273.69 275.55 4475 1
mu[2] 267.14 0.02 1.28 264.64 266.26 267.12 268.00 269.68 4593 1
sigma[1] 60.01 0.02 1.28 57.55 59.15 60.00 60.86 62.53 3656 1
sigma[2] 54.94 0.02 1.12 52.79 54.18 54.92 55.70 57.19 3673 1
nu 5.27 0.01 0.38 4.58 5.01 5.25 5.51 6.05 4498 1
rho 0.81 0.00 0.01 0.79 0.80 0.81 0.81 0.82 4869 1
cov[1,1] 3603.09 2.54 153.48 3311.44 3498.40 3599.66 3703.53 3909.89 3659 1
cov[1,2] 2670.69 2.11 121.75 2440.79 2585.48 2667.90 2750.53 2920.02 3333 1
cov[2,1] 2670.69 2.11 121.75 2440.79 2585.48 2667.90 2750.53 2920.02 3333 1
cov[2,2] 3019.99 2.04 123.51 2787.14 2935.61 3016.10 3102.72 3271.26 3671 1
x_rand[1] 273.92 0.82 73.68 128.22 230.21 274.02 316.06 420.89 8061 1
x_rand[2] 269.13 0.75 67.33 133.79 228.98 268.90 307.33 404.88 8079 1
attempt 0.00 0.00 0.06 0.00 0.00 0.00 0.00 0.00 7660 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ -24232.17 0.03 1.77 -24236.45 -24233.10 -24231.82 -24230.89 -24229.77 3293 1
Samples were drawn using NUTS(diag_e) at Mon Feb 5 23:41:09 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.--------------------------------------------"
print(fit_ereg)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.15 0.00 0.00 0.14 0.14 0.15 0.15 0.15 3942 1
mu[2] 0.14 0.00 0.00 0.14 0.14 0.14 0.15 0.15 3878 1
sigma[1] 0.09 0.00 0.00 0.08 0.09 0.09 0.09 0.09 3623 1
sigma[2] 0.09 0.00 0.00 0.08 0.08 0.09 0.09 0.09 3466 1
nu 3.39 0.00 0.21 3.02 3.25 3.38 3.53 3.82 4641 1
rho 0.66 0.00 0.02 0.63 0.65 0.66 0.67 0.69 5517 1
cov[1,1] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.01 3627 1
cov[1,2] 0.01 0.00 0.00 0.00 0.00 0.01 0.01 0.01 3292 1
cov[2,1] 0.01 0.00 0.00 0.00 0.00 0.01 0.01 0.01 3292 1
cov[2,2] 0.01 0.00 0.00 0.01 0.01 0.01 0.01 0.01 3471 1
x_rand[1] 0.18 0.00 0.11 0.02 0.11 0.16 0.23 0.43 7911 1
x_rand[2] 0.17 0.00 0.10 0.02 0.11 0.16 0.22 0.41 7898 1
attempt 0.16 0.00 0.43 0.00 0.00 0.00 0.00 1.00 8067 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 6053.37 0.03 1.73 6049.27 6052.43 6053.71 6054.65 6055.79 3589 1
Samples were drawn using NUTS(diag_e) at Tue Feb 6 22:53:58 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
print('---------------------------- Skip Prob.--------------------------------------------')
[1] "---------------------------- Skip Prob.--------------------------------------------"
print(fit_eskip)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1;
post-warmup draws per chain=2000, total post-warmup draws=8000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu[1] 0.42 0.00 0.00 0.41 0.42 0.42 0.42 0.43 4394 1
mu[2] 0.47 0.00 0.00 0.46 0.46 0.47 0.47 0.47 4472 1
sigma[1] 0.25 0.00 0.00 0.24 0.24 0.25 0.25 0.25 4291 1
sigma[2] 0.22 0.00 0.00 0.21 0.22 0.22 0.22 0.22 4205 1
nu 110.17 0.30 24.51 69.67 92.41 107.29 125.40 165.37 6568 1
rho 0.91 0.00 0.00 0.90 0.91 0.91 0.91 0.91 4932 1
cov[1,1] 0.06 0.00 0.00 0.06 0.06 0.06 0.06 0.06 4304 1
cov[1,2] 0.05 0.00 0.00 0.05 0.05 0.05 0.05 0.05 3900 1
cov[2,1] 0.05 0.00 0.00 0.05 0.05 0.05 0.05 0.05 3900 1
cov[2,2] 0.05 0.00 0.00 0.04 0.05 0.05 0.05 0.05 4205 1
x_rand[1] 0.45 0.00 0.22 0.06 0.29 0.44 0.61 0.90 7138 1
x_rand[2] 0.49 0.00 0.20 0.12 0.34 0.48 0.63 0.90 7290 1
attempt 0.05 0.00 0.22 0.00 0.00 0.00 0.00 1.00 7109 1
max_attempts 10.00 NaN 0.00 10.00 10.00 10.00 10.00 10.00 NaN NaN
lp__ 5351.87 0.03 1.69 5347.60 5350.96 5352.16 5353.13 5354.21 3356 1
Samples were drawn using NUTS(diag_e) at Sun Feb 25 01:56:18 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).
# stan_trace(fit_egd, pars=c("rho", "mu", "sigma", "nu"))
# stan_dens(fit_egd, pars=c("rho", "mu", "sigma", "nu"), separate_chains = TRUE)
# stan_plot(fit_egd, pars=c("rho", "mu", "sigma", "nu"))
# Gaze Duration
stan_trace(fit_egd)
stan_dens(fit_egd, separate_chains = TRUE)
stan_plot(fit_egd)
# Go Past Time
stan_trace(fit_egpt)
stan_dens(fit_egpt, separate_chains = TRUE)
stan_plot(fit_egpt)
# Total Duration
stan_trace(fit_etd)
stan_dens(fit_etd, separate_chains = TRUE)
stan_plot(fit_etd)
# FPReg
stan_trace(fit_ereg)
stan_dens(fit_ereg, separate_chains = TRUE)
stan_plot(fit_ereg)
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
rho_egd = as.numeric(extract(fit_egd, "rho")[[1]])
mean = mean(rho_egd)
crI = quantile(rho_egd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_egd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.7479
HPD: [0.7278, 0.7669]
crI: [0.7278, 0.767]
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
rho_egpt = as.numeric(extract(fit_egpt, "rho")[[1]])
mean = mean(rho_egpt)
crI = quantile(rho_egpt, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_egpt), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6334
HPD: [0.6052, 0.6617]
crI: [0.6044, 0.6612]
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
rho_etd = as.numeric(extract(fit_etd, "rho")[[1]])
mean = mean(rho_etd)
crI = quantile(rho_etd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_etd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.8095
HPD: [0.7939, 0.825]
crI: [0.7937, 0.8248]
print('---------------------------- First Pass Regression --------------------------------------------')
[1] "---------------------------- First Pass Regression --------------------------------------------"
rho_ereg = as.numeric(extract(fit_ereg, "rho")[[1]])
mean = mean(rho_ereg)
crI = quantile(rho_ereg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6638
HPD: [0.6339, 0.6922]
crI: [0.6337, 0.6921]
print('---------------------------- Skip --------------------------------------------')
[1] "---------------------------- Skip --------------------------------------------"
rho_eskip = as.numeric(extract(fit_eskip, "rho")[[1]])
mean = mean(rho_eskip)
crI = quantile(rho_eskip, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_eskip), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
Mean: 0.9081
HPD: [0.9012, 0.9148]
crI: [0.9011, 0.9148]
print('---------------------------- Gaze Duration--------------------------------------------')
egd_rand <- extract(fit_egd, "x_rand")[[1]]
# x_rand_filtered <- x_rand[apply(x_rand, 1, function(x) all(x > 0)),]
# x_rand_filtered
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 400), ylim=c(0, 700), type="n",
xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(egd_rand[,1], egd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(egd_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(egd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(egd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- Go Past Time--------------------------------------------')
egpt_rand <- extract(fit_egpt, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Go Past Time") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(egpt_rand[,1], egpt_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(egpt_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(egpt_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(egpt_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- Total Duration--------------------------------------------')
etd_rand <- extract(fit_etd, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Total Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(etd_rand[,1], etd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(etd_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(etd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(etd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression --------------------------------------------')
ereg_rand <- extract(fit_ereg, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "First Pass Regression") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(ereg_rand[,1], ereg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(ereg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(ereg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
Bayesian – correlation between MoTR and word level statistics
print("Log Frequency")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$freq)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$freq)$estimate)
# View(stats_cor_df)
stats_cor_df %>%
gather(measure, value, c(7, 13)) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
mfreq_temp <- stats_cor_df[c("motr_value", "freq")] %>%
data.matrix()
efreq_temp <- stats_cor_df[c("eyetr_value", "freq")] %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(mfreq_temp, pch = 16, col = "blue",
main = "MoTR RTs and Word Frequency")
# Plot the first data matrix gd_temp
plot(efreq_temp, pch = 16, col = "blue",
main = "EyeTR RTs and Word Frequency")
motr & frequency
mfreq_data = list(x=mfreq_temp, N=nrow(mfreq_temp))
fit_mfreq = stan(
file="stan_models/stats_correlation.stan",
data=mfreq_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
# verbose = FALSE
)
# Save the model
fit_mfreq@stanmodel@dso <- new("cxxdso")
saveRDS(fit_mfreq, file = paste0("./bayesian_models/bayesian_models_correlation/motr_freq_cor.rds"))
eyetr & frequency
efreq_data = list(x=efreq_temp, N=nrow(efreq_temp))
fit_efreq = stan(
file="stan_models/stats_correlation.stan",
data=efreq_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
# verbose = FALSE
)
# Save the model
fit_efreq@stanmodel@dso <- new("cxxdso")
saveRDS(fit_efreq, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_freq_cor.rds"))
print("Length")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$len)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$len)$estimate)
# View(stats_cor_df)
stats_cor_df %>%
gather(measure, value, c(9, 13)) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
mlen_temp <- stats_cor_df[c("motr_value", "len")] %>%
data.matrix()
elen_temp <- stats_cor_df[c("eyetr_value", "len")] %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(mlen_temp, pch = 16, col = "blue",
main = "MoTR RTs and Word Length")
# Plot the first data matrix gd_temp
plot(elen_temp, pch = 16, col = "blue",
main = "EyeTR RTs and Word Length")
motr & length
mlen_data = list(x=mlen_temp, N=nrow(mlen_temp))
fit_mlen = stan(
file="stan_models/stats_correlation_len_normal.stan",
data=mlen_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
# verbose = FALSE
)
# Save the model
fit_mlen@stanmodel@dso <- new("cxxdso")
saveRDS(fit_mlen, file = paste0("./bayesian_models/bayesian_models_correlation/motr_len_cor.rds"))
eyetr & length
elen_data = list(x=elen_temp, N=nrow(elen_temp))
fit_elen = stan(
file="stan_models/stats_correlation_len_normal.stan",
data=elen_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
# verbose = FALSE
)
# Save the model
fit_elen@stanmodel@dso <- new("cxxdso")
saveRDS(fit_elen, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_len_cor.rds"))
print("Surprisal")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$surp)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$surp)$estimate)
# View(stats_cor_df)
stats_cor_df %>%
gather(measure, value, c(8, 13)) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
msurp_temp <- stats_cor_df[c("motr_value", "surp")] %>%
data.matrix()
esurp_temp <- stats_cor_df[c("eyetr_value", "surp")] %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(msurp_temp, pch = 16, col = "blue",
main = "MoTR RTs and Surprisal")
# Plot the first data matrix gd_temp
plot(esurp_temp, pch = 16, col = "blue",
main = "EyeTR RTs and Surprisal")
motr & surprisal
msurp_data = list(x=msurp_temp, N=nrow(msurp_temp))
fit_msurp = stan(
file="stan_models/stats_correlation.stan",
data=msurp_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
# verbose = FALSE
)
# Save the model
fit_msurp@stanmodel@dso <- new("cxxdso")
saveRDS(fit_msurp, file = paste0("./bayesian_models/bayesian_models_correlation/motr_surp_cor.rds"))
eyetr & surprisal
esurp_data = list(x=esurp_temp, N=nrow(esurp_temp))
fit_esurp = stan(
file="stan_models/stats_correlation.stan",
data=esurp_data,
iter=4000,
chains=4,
cores=8,
seed=444,
# control=list(adapt_delta=0.99),
# verbose = FALSE
)
# Save the model
fit_esurp@stanmodel@dso <- new("cxxdso")
saveRDS(fit_esurp, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_surp_cor.rds"))
fit_mfreq = readRDS("./bayesian_models/bayesian_models_correlation/motr_freq_cor.rds")
fit_efreq = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_freq_cor.rds")
fit_mlen = readRDS("./bayesian_models/bayesian_models_correlation/motr_len_cor.rds")
fit_elen = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_len_cor.rds")
fit_msurp = readRDS("./bayesian_models/bayesian_models_correlation/motr_surp_cor.rds")
fit_esurp = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_surp_cor.rds")
print('---------------------------- MoTR & Log Frequency --------------------------------------------')
print(fit_mfreq)
print('---------------------------- EyeTR & Log Frequency --------------------------------------------')
print(fit_efreq)
print('---------------------------- MoTR & Length --------------------------------------------')
print(fit_mlen)
print('---------------------------- EyeTR & Length --------------------------------------------')
print(fit_elen)
print('---------------------------- MoTR & Surprisal --------------------------------------------')
print(fit_msurp)
print('---------------------------- EyeTR & Surprisal --------------------------------------------')
print(fit_esurp)
# MoTR & Log Freq
stan_trace(fit_mfreq)
stan_dens(fit_mfreq, separate_chains = TRUE)
stan_plot(fit_mfreq)
# EyeTR & Log Freq
stan_trace(fit_efreq)
stan_dens(fit_efreq, separate_chains = TRUE)
stan_plot(fit_efreq)
# MoTR & Len
stan_trace(fit_mlen)
stan_dens(fit_mlen, separate_chains = TRUE)
stan_plot(fit_mlen)
# EyeTR & Len
stan_trace(fit_elen)
stan_dens(fit_elen, separate_chains = TRUE)
stan_plot(fit_elen)
# MoTR & Surprisal
stan_trace(fit_msurp)
stan_dens(fit_msurp, separate_chains = TRUE)
stan_plot(fit_msurp)
# EyeTR & Surprisal
stan_trace(fit_esurp)
stan_dens(fit_esurp, separate_chains = TRUE)
stan_plot(fit_esurp)
print('---------------------------- MoTR & Log Freq --------------------------------------------')
rho_mfreq = as.numeric(extract(fit_mfreq, "rho")[[1]])
mean = mean(rho_mfreq)
crI = quantile(rho_mfreq, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mfreq), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- EyeTR & Log Freq --------------------------------------------')
rho_efreq = as.numeric(extract(fit_efreq, "rho")[[1]])
mean = mean(rho_efreq)
crI = quantile(rho_efreq, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_efreq), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- MoTR & Length --------------------------------------------')
rho_mlen = as.numeric(extract(fit_mlen, "rho")[[1]])
mean = mean(rho_mlen)
crI = quantile(rho_mlen, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mlen), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- EyeTR & Length --------------------------------------------')
rho_elen = as.numeric(extract(fit_elen, "rho")[[1]])
mean = mean(rho_elen)
crI = quantile(rho_elen, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_elen), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- MoTR & Surprisal --------------------------------------------')
rho_msurp = as.numeric(extract(fit_msurp, "rho")[[1]])
mean = mean(rho_msurp)
crI = quantile(rho_msurp, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_msurp), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- EyeTR & Surprisal --------------------------------------------')
rho_esurp = as.numeric(extract(fit_esurp, "rho")[[1]])
mean = mean(rho_esurp)
crI = quantile(rho_esurp, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_esurp), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
print('---------------------------- MoTR & Log Frequency--------------------------------------------')
mfreq_rand <- extract(fit_mfreq, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 12), type="n",
xlab = "MoTR value", ylab = "Log Frequency", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mfreq_rand[,1], mfreq_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(mfreq_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mfreq_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mfreq_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- EyeTR & Log Frequency--------------------------------------------')
efreq_rand <- extract(fit_efreq, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 500), ylim=c(0, 12), type="n",
xlab = "Eye tracking value", ylab = "Log Frequency", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(efreq_rand[,1], efreq_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(efreq_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(efreq_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(efreq_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- MoTR & Length --------------------------------------------')
mlen_rand <- extract(fit_mlen, "x_rand")[[1]]
# mlen_rand
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
xlab = "MoTR value", ylab = "Word Length", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(mlen_rand[,1], mlen_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(mlen_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(mlen_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlen_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- EyeTR & Length --------------------------------------------')
elen_rand <- extract(fit_elen, "x_rand")[[1]]
# elen_rand
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
xlab = "EyeTR value", ylab = "Word Length", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(elen_rand[,1], elen_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(elen_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(elen_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(elen_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- MoTR & Surprisal --------------------------------------------')
msurp_rand <- extract(fit_msurp, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
xlab = "MoTR value", ylab = "Word Surprisal", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(msurp_rand [,1], msurp_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(msurp_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(msurp_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(msurp_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- EyeTR & Surprisal --------------------------------------------')
esurp_rand <- extract(fit_esurp, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
xlab = "EyeTR value", ylab = "Word Surprisal", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(esurp_rand [,1], esurp_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(esurp_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(esurp_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(esurp_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print("EyeTR vs. EyeTR Fisrt Pass Regression Prob. < 0.3 ")
ereg_df = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value)) %>%
filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value_1 = pmax(value_1, 1e-5),
eyetr_value_2 = pmax(value_2, 1e-5))
ereg_df_low = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value)) %>%
filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value_1 = pmax(value_1, 1e-5),
eyetr_value_2 = pmax(value_2, 1e-5)) %>%
filter(eyetr_value_1 < 0.3)
# View(ereg_df_low)
ereg_df_high = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
# summarize(value = mean(value)) %>%
filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
spread(measure, value) %>%
# smoothing, if includes 0s
mutate(eyetr_value_1 = pmax(value_1, 1e-5),
eyetr_value_2 = pmax(value_2, 1e-5)) %>%
filter(eyetr_value_1 >= 0.3)
# View(ereg_df_high)
print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$estimate)
print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$p.value)
print(cor.test(ereg_df_low$eyetr_value_1, ereg_df_low$eyetr_value_2)$estimate)
print(cor.test(ereg_df_low$eyetr_value_1, ereg_df_low$eyetr_value_2)$p.value)
print(cor.test(ereg_df_high$eyetr_value_1, ereg_df_high$eyetr_value_2)$estimate)
print(cor.test(ereg_df_high$eyetr_value_1, ereg_df_high$eyetr_value_2)$p.value)
# View(egd_df)
ereg_df %>%
gather(measure, value, 5:6) %>%
ggplot(aes(x = value)) +
geom_density() +
facet_wrap(~measure, scales = "free") +
theme_bw() +
scale_fill_brewer(palette = "Set1")
ereg_temp <- ereg_df[c("eyetr_value_1", "eyetr_value_2")] %>%
drop_na() %>%
data.matrix()
ereg_temp_low <- ereg_df_low[c("eyetr_value_1", "eyetr_value_2")] %>%
drop_na() %>%
data.matrix()
ereg_temp_high <- ereg_df_high[c("eyetr_value_1", "eyetr_value_2")] %>%
drop_na() %>%
data.matrix()
# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 3))
# Plot the first data matrix gd_temp
plot(ereg_temp, pch = 16, col = "blue",
main = "FPReg all data Not Log-Transformed")
plot(ereg_temp_low, pch = 16, col = "blue",
main = "FPReg < 0.3 Not Log-Transformed")
plot(ereg_temp_high, pch = 16, col = "blue",
main = "FPReg > 0.3 Not Log-Transformed")
# -------fit model eyetr vs. eyetr FPReg <0.3 & >=0.3 ----------
reg_data = list(x=ereg_temp, N=nrow(ereg_temp))
fit_reg = stan(
# file="stan_models/bivariate_beta_correlation_reg.stan",
file = "stan_models/bivariate_normal_reg.stan",
data=reg_data,
iter=4000,
chains=4,
cores=4,
seed=444,
# control=list(adapt_delta=0.99),
verbose = FALSE
)
# Save the model
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_all_data.rds"))
exploratory: divide eye tracking regression data into two
parts.
# fit_ereg_all = readRDS("./eyetr_eyetr_FPReg_cor_all_data.rds")
fit_ereg_all = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor.rds")
fit_ereg_low = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_00-03.rds")
fit_ereg_high = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_03-1.rds")
print('---------------------------- First Pass Regression Prob. all data --------------------------------------------')
print(fit_ereg_all)
print('---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------')
print(fit_ereg_low)
print('---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------')
print(fit_ereg_high)
# # FPReg all data
stan_trace(fit_ereg_all)
stan_dens(fit_ereg_all, separate_chains = TRUE)
stan_plot(fit_ereg_all)
# # FPReg < 0.3
stan_trace(fit_ereg_low)
stan_dens(fit_ereg_low, separate_chains = TRUE)
stan_plot(fit_ereg_low)
# FPReg >= 0.3
stan_trace(fit_ereg_high)
stan_dens(fit_ereg_high, separate_chains = TRUE)
stan_plot(fit_ereg_high)
print('---------------------------- First Pass Regression all data--------------------------------------------')
rho_ereg_all = as.numeric(extract(fit_ereg_all, "rho")[[1]])
mean = mean(rho_ereg_all)
crI = quantile(rho_ereg_all, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_all), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- First Pass Regression < 0.3--------------------------------------------')
rho_ereg_low = as.numeric(extract(fit_ereg_low, "rho")[[1]])
mean = mean(rho_ereg_low)
crI = quantile(rho_ereg_low, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_low), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- First Pass Regression >= 0.3--------------------------------------------')
rho_ereg_high = as.numeric(extract(fit_ereg_high, "rho")[[1]])
mean = mean(rho_ereg_high)
crI = quantile(rho_ereg_high, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_high), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- First Pass Regression all data --------------------------------------------')
eallreg_rand <- extract(fit_ereg_all, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(eallreg_rand[,1], eallreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp, pch=16, col="red")
# add dataEllipse with color
dataEllipse(eallreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(eallreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression < 0.3 --------------------------------------------')
elowreg_rand <- extract(fit_ereg_low, "x_rand")[[1]]
# print(elowreg_rand)
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(elowreg_rand[,1], elowreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp_low, pch=16, col="red")
# add dataEllipse with color
dataEllipse(elowreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(elowreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print('---------------------------- First Pass Regression >= 0.3 --------------------------------------------')
ehighreg_rand_samples <- extract(fit_ereg_high, "x_rand")[[1]]
# print(mhighreg_rand_samples)
selected_indices <- sample(1:nrow(ehighreg_rand_samples), 900)
ehighreg_rand <- ehighreg_rand_samples[selected_indices, ]
# mhighreg_rand <- extract(fit_mreg_high, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank
# add points for x_rand with color
points(ehighreg_rand[,1], ehighreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp_high, pch=16, col="red")
# add dataEllipse with color
dataEllipse(ehighreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(ehighreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
LS0tCnRpdGxlOiAiQ29ycmVsYXRpb24gQW5hbHlzaXMgZm9yIE1vVFIgb24gUHJvdm8gRGF0YSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnNoaGggPC0gc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzICMgSXQncyBhIGxpYnJhcnksIHNvIHNoaGghCgpzaGhoKGxpYnJhcnkoIG1nY3YgKSkKc2hoaChsaWJyYXJ5KGRwbHlyKSkKc2hoaChsaWJyYXJ5KGdncGxvdDIpKQpzaGhoKGxpYnJhcnkobG1lNCkpCnNoaGgobGlicmFyeSh0aWR5bXYpKQpzaGhoKGxpYnJhcnkoZ2FtbHNzKSkKc2hoaChsaWJyYXJ5KGdzdWJmbikpCnNoaGgobGlicmFyeShsbWVyVGVzdCkpCnNoaGgobGlicmFyeSh0aWR5dmVyc2UpKQpzaGhoKGxpYnJhcnkoYm9vdCkpCnNoaGgobGlicmFyeShyc2FtcGxlKSkKc2hoaChsaWJyYXJ5KHBsb3RyaXgpKQpzaGhoKGxpYnJhcnkoZ2dyZXBlbCkpCnNoaGgobGlicmFyeShtZ2N2KSkKCnNoaGgobGlicmFyeShicm1zKSkKc2hoaChsaWJyYXJ5KGJheWVzcGxvdCkpCnNoaGgobGlicmFyeShwYXRjaHdvcmspKQpzaGhoKGxpYnJhcnkoTUFTUykpCnNoaGgobGlicmFyeSh0aWR5cikpCnNoaGgobGlicmFyeShleHRyYURpc3RyKSkKc2hoaChsaWJyYXJ5KHB1cnJyKSkKIyBGb3IgZXhlcmNpc2VzIHdpdGggU3RhbiBjb2RlCnNoaGgobGlicmFyeShyc3RhbikpCm9wdGlvbnMobWMuY29yZXMgPSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSkKcnN0YW5fb3B0aW9ucyhhdXRvX3dyaXRlID0gRkFMU0UpCgpzaGhoKGxpYnJhcnkoY2FyKSkKc2hoaChsaWJyYXJ5KGNvZGEpKQpzaGhoKGxpYnJhcnkoZ3JpZEV4dHJhKSkKCnRoZW1lX3NldCh0aGVtZV9idygpKQpvcHRpb25zKGRpZ2l0cz00KQpvcHRpb25zKHNjaXBlbj05OTkpCnNldC5zZWVkKDQ0NCkKcGlwZV9tZXNzYWdlID0gZnVuY3Rpb24oLmRhdGEsIHN0YXR1cykge21lc3NhZ2Uoc3RhdHVzKTsgLmRhdGF9CgpgYGAKCgojIFJlYWQgaW4gTW9UUiBEYXRhCgpgYGB7cn0KCnJhdGUgPSAxNjAKCmZpbGVfcHJlZml4ID0gIi4uL2RhdGEvcHJvdm9fZjE2MC8iCmZuYW1lcyA9IGxpc3QuZmlsZXMocGF0aD1maWxlX3ByZWZpeCkKCmRmID0gZGF0YS5mcmFtZSgpCmZvciAoZiBpbiBmbmFtZXMpIHsKICB0ZW1wID0gcmVhZC5jc3YocGFzdGUwKGZpbGVfcHJlZml4LCAiLyIsIGYpKSAlPiUKICAgIG11dGF0ZShzdWJqID0gc3RyX3JlbW92ZShmLCAiX3JlYWRpbmdfbWVhc3VyZXMuY3N2IikpCiAgZGYgPSByYmluZChkZiwgdGVtcCkKfQoKIyBGaWx0ZXIgb3V0IHJlYWRlcnMgd2hvc2UgYWNjdXJhY3kgdG8gdGhlIGNvbXByZWhlbnNpb24gcXVlc3Rpb25zIHdlcmUgbGVzcyB0aGFuIDgwJS4KZmlsdGVyX2RmID0gZGYgJT4lCiAgZ3JvdXBfYnkocGFyYV9uciwgc3ViaikgJT4lIHN1bW1hcmlzZShjb3JyZWN0ID0gaWZfZWxzZSh1bmlxdWUoY29ycmVjdG5lc3MpID09IDEsIDEsIDApKSAlPiUgdW5ncm91cCgpICU+JQogIGRyb3BfbmEoKSAlPiUKICBncm91cF9ieShzdWJqKSAlPiUgc3VtbWFyaXNlKHBfY29ycmVjdCA9IG1lYW4oY29ycmVjdCkpICU+JSB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHBfY29ycmVjdCA9IHJvdW5kKHBfY29ycmVjdCwgZGlnaXRzID0gMikpCgpmaWx0ZXJfZGYgPSBmaWx0ZXJfZGYgJT4lIGZpbHRlcihwX2NvcnJlY3QgPCAwLjgpCmZpbHRlcl9saXN0ID0gZmlsdGVyX2RmJHN1YmoKcGlsb3RfZXhjZXB0aW9ucyA8LSBjKCJyZWFkZXJfMjU1IiwgInJlYWRlcl8yNTYiLCAicmVhZGVyXzI1OSIsICJyZWFkZXJfMjYxIiwgInJlYWRlcl8yNjIiLCAicmVhZGVyXzI2MyIpCgpyYXdfZGYgPSBkZiAlPiUKICBmaWx0ZXIoISBzdWJqICVpbiUgYyhmaWx0ZXJfbGlzdCkgfCAoc3ViaiAlaW4lIHBpbG90X2V4Y2VwdGlvbnMpKSAlPiUKICBtdXRhdGUod29yZCA9IHN0cl90cmltKHdvcmQpKSAlPiUKICBtdXRhdGUoc3ViaiA9IHN0cl9yZW1vdmUoc3ViaiwgInJlYWRlcl8iKSkgJT4lCiAgbXV0YXRlKHN1YmogPSBhcy5jaGFyYWN0ZXIoc3ViaikpICU+JQogIG11dGF0ZShGUFJlZyA9IGlmX2Vsc2UodG90YWxfZHVyYXRpb24gPT0gMCwgLTEsIEZQUmVnKSkgJT4lICNJZiB0aGUgd29yZCBpcyBza2lwcGVkIHdlIGNhbid0IHNheSB0aGF0IGl0IHdhc24ndCByZWdyZXNzZWQgb24gdGhlIGZpcnN0IHBhc3MuIFNldCB0byBhICJOQSIKICBtdXRhdGUoc2tpcCA9IGlmX2Vsc2UoRlBGaXggPT0gMSwgMCwgMSkpICU+JSAjIHVzZSB0aGUgc2FtZSBkZWZpbmF0aW9uIGFzIGluIHByb3ZvIHBhcGVyCiAgZHBseXI6OnNlbGVjdChzdWJqLCBleHByX2lkLCBjb25kX2lkLCBwYXJhX25yLCB3b3JkLCB3b3JkX25yLCBmaXJzdF9kdXJhdGlvbiwgdG90YWxfZHVyYXRpb24sIGdhemVfZHVyYXRpb24sIGdvX3Bhc3RfdGltZSwgRlBSZWcsIHNraXApICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCA3OjEwKSAlPiUKICBncm91cF9ieShwYXJhX25yLCBzdWJqLCBtZXRyaWMsIGNvbmRfaWQsIGV4cHJfaWQpICU+JQogIG11dGF0ZShmaXhlZCA9IGlmX2Vsc2UodmFsdWUgPiAwLCAxLCAwKSwKICAgICAgICAgbl9maXhlZCA9IHN1bShmaXhlZCksCiAgICAgICAgIG5fd29yZHMgPSBuKCkpICU+JQogICAgdW5ncm91cCgpICU+JQogIG11dGF0ZShmaXhfdGhyZXNob2xkID0gbl9maXhlZCA+IChuX3dvcmRzIC8gNSkpICU+JQogIG11dGF0ZShza2ltbWluZyA9IGlmX2Vsc2UoZml4X3RocmVzaG9sZCA9PSBGLFQsIEYpKSAlPiUKICBmaWx0ZXIoc2tpbW1pbmcgPT0gRikgJT4lCiAgc3ByZWFkKG1ldHJpYywgdmFsdWUpICU+JQogIGRwbHlyOjpzZWxlY3QoLWZpeGVkLCAtbl9maXhlZCwgLW5fd29yZHMsIC1maXhfdGhyZXNob2xkLCAtc2tpbW1pbmcpCmxlbmd0aCh1bmlxdWUocmF3X2RmJHN1YmopKQojIFZpZXcocmF3X2RmKQoKZGYgJT4lCiAgZmlsdGVyKCEgc3ViaiAlaW4lIGMoZmlsdGVyX2xpc3QpIHwgKHN1YmogJWluJSBwaWxvdF9leGNlcHRpb25zKSkgJT4lCiAgZmlsdGVyKEZQUmVnID49IDApICU+JQogIGRwbHlyOjpzZWxlY3QoRlBSZWcpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKEZQUmVnKSkKCmRmICU+JQogIGZpbHRlcighIHN1YmogJWluJSBjKGZpbHRlcl9saXN0KSB8IChzdWJqICVpbiUgcGlsb3RfZXhjZXB0aW9ucykpICU+JQogIGRwbHlyOjpzZWxlY3QoRlBGaXgpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKEZQRml4KSkKCgpgYGAKCmBgYHtyfQpWaWV3KHJhd19kZikKYGBgCgoKYGBge3J9CiMgQXZlcmFnZSBhY3Jvc3Mgc3ViamVjdHMKbW90cl9hZ2dfZGYgPSByYXdfZGYgJT4lCiAgZ2F0aGVyKG1ldHJpYywgdmFsdWUsIDc6MTIpICU+JQogICAgZmlsdGVyKHZhbHVlID49IDApICU+JSAjUmVtb3ZlcyB0aGUgIk5BIiB2YWx1ZXMgZm9yIEZQUmVnCiAgCiAgICAjID09PT0gUmVtb3ZlIHNraXBwZWQgd29yZHMKICAgIG11dGF0ZSh6ZXJvID0gaWZfZWxzZSghbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgdmFsdWUgPT0gMCxULCBGKSkgJT4lCiAgICBmaWx0ZXIoemVybyA9PSBGKSAlPiUKICAKICAgIGRyb3BfbmEoKSAlPiUKICAgIGdyb3VwX2J5KHBhcmFfbnIsIHdvcmRfbnIsIHdvcmQsIG1ldHJpYykgJT4lCiAgICAKICAgICMgPT09IFJlbW92ZSBvdXRsaWVycyA+IDNTRAogICAgICAjIG11dGF0ZShvdXRsaWVyID0gaWZfZWxzZShtZXRyaWMgIT0gIkZQUmVnIiAmIHZhbHVlID4gKG1lYW4odmFsdWUpICsgMyAqIHNkKHZhbHVlKSksIFQsIEYpKSAlPiUgZmlsdGVyKG91dGxpZXIgPT0gRikgJT4lCiAgCiAgICAgIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpLCBuc3ViaiA9IGxlbmd0aCh1bmlxdWUoc3ViaikpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShwYXJhX25yLCB3b3JkX25yKSAlPiUKICByZW5hbWUodGV4dF9pZCA9IHBhcmFfbnIsIHdvcmRfdGV4dF9pZHggPSB3b3JkX25yLCBtb3RyX3ZhbHVlID0gdmFsdWUpCiMgVmlldyhtb3RyX2FnZ19kZikKCmBgYAoKCgoKIyBDb21wYXJpc29uIHRvIFByb3ZvCgoKYGBge3J9CiMgUmVhZCBpbiBQcm92byBzdXJwcmlzYWwsIGZyZXF1ZW5jeSBhbmQgbGVuZ3RoIGRhdGEKcHJvdm9fbW9kZWxpbmdfZGYgPSByZWFkLmNzdigiLi4vZGF0YS9wcm92b19zdGF0cy5jc3YiKSAlPiUKICBkcGx5cjo6c2VsZWN0KHRleHRfaWQsIHNlbnRfaWQsIHRyaWdnZXJfaWR4LCB3b3JkLCBmcmVxLCBzdXJwLCBsZW4pICU+JQogIHJlbmFtZSh3b3JkX2lkeCA9IHRyaWdnZXJfaWR4KQoKcHJvdm9fbW9kZWxpbmdfZGYKCmBgYAoKYGBge3J9CiMgUmVhZCBpbiBQcm92byBleWV0cmFja2luZyBkYXRhCgpwcm92b19yYXdfZGYgPSByZWFkLmNzdigiLi4vZGF0YS9wcm92b19leWV0cmFja2luZy5jc3YiKQoKYGBgCgpgYGB7cn0KCiMgdW5pcXVlKHByb3ZvX3Jhd19kZiRQYXJ0aWNpcGFudF9JRCkKIyBsZW5ndGgodW5pcXVlKHByb3ZvX3Jhd19kZiRQYXJ0aWNpcGFudF9JRCkpCgpwcm92b19leWV0cmFja2luZ19kZiA9IHByb3ZvX3Jhd19kZiAlPiUKICBkcGx5cjo6c2VsZWN0KFBhcnRpY2lwYW50X0lELCBUZXh0X0lELCBTZW50ZW5jZV9OdW1iZXIsIFdvcmRfSW5fU2VudGVuY2VfTnVtYmVyLCBXb3JkLCBXb3JkX051bWJlciwgSUFfRklSU1RfRklYX1BST0dSRVNTSVZFLCBJQV9GSVJTVF9SVU5fRFdFTExfVElNRSwgSUFfRFdFTExfVElNRSwgSUFfUkVHUkVTU0lPTl9QQVRIX0RVUkFUSU9OLCBJQV9SRUdSRVNTSU9OX09VVCwgSUFfU0tJUCkgJT4lCiAgcmVuYW1lKCAjZmlyc3RfZHVyYXRpb24gPSBJQV9GSVJTVF9GSVhBVElPTl9EVVJBVElPTiwgICAKICAgICAgICAgIGdhemVfZHVyYXRpb24gPSBJQV9GSVJTVF9SVU5fRFdFTExfVElNRSwKICAgICAgICAgIHRvdGFsX2R1cmF0aW9uID0gSUFfRFdFTExfVElNRSwKICAgICAgICAgIGdvX3Bhc3RfdGltZSA9IElBX1JFR1JFU1NJT05fUEFUSF9EVVJBVElPTiwKICAgICAgICAgIHN1YmogPSBQYXJ0aWNpcGFudF9JRCwKICAgICAgICAgIHRleHRfaWQgPSBUZXh0X0lELAogICAgICAgICAgc2VudF9pZCA9IFNlbnRlbmNlX051bWJlciwKICAgICAgICAgIHdvcmRfaWR4ID0gV29yZF9Jbl9TZW50ZW5jZV9OdW1iZXIsCiAgICAgICAgICB3b3JkX3RleHRfaWR4ID0gV29yZF9OdW1iZXIsICAgIyBJQV9JRD8KICAgICAgICAgIHdvcmQgPSBXb3JkLCAgICAgICMgV29yZD8KICAgICAgICAgIEZQUmVnID0gSUFfUkVHUkVTU0lPTl9PVVQsCiAgICAgICAgICBza2lwID0gSUFfU0tJUCwKICAgICAgICAgIGZmX3Byb2dyZXNzaXZlID0gSUFfRklSU1RfRklYX1BST0dSRVNTSVZFKSAlPiUKICBtdXRhdGUoZmlyc3RfZHVyYXRpb24gPSBnYXplX2R1cmF0aW9uKSAlPiUKICBtdXRhdGUoZ2F6ZV9kdXJhdGlvbiA9IGlmX2Vsc2UoZmZfcHJvZ3Jlc3NpdmUgPT0gMCwgMCwgYXMuZG91YmxlKGdhemVfZHVyYXRpb24pKSwKICAgICAgICAgZ29fcGFzdF90aW1lID0gaWZfZWxzZShmZl9wcm9ncmVzc2l2ZSA9PSAwLCAwLCBhcy5kb3VibGUoZ29fcGFzdF90aW1lKSkpICU+JQogIGRwbHlyOjpzZWxlY3QoLWZmX3Byb2dyZXNzaXZlKSAlPiUKICAKICBtdXRhdGUoCiAgICBnYXplX2R1cmF0aW9uID0gaWZfZWxzZSh0b3RhbF9kdXJhdGlvbiA9PSAwLCAwLCBhcy5kb3VibGUoZ2F6ZV9kdXJhdGlvbikpLAogICAgICBnb19wYXN0X3RpbWUgPSBpZl9lbHNlKHRvdGFsX2R1cmF0aW9uID09IDAsIDAsIGFzLmRvdWJsZShnb19wYXN0X3RpbWUpKSwKICAgICAgRlBSZWcgPSBpZl9lbHNlKHRvdGFsX2R1cmF0aW9uID09IDAsIC0xLCBhcy5kb3VibGUoRlBSZWcpKSwKICAgICAgZmlyc3RfZHVyYXRpb24gPSAgaWZfZWxzZSh0b3RhbF9kdXJhdGlvbiA9PSAwLCAwLCBhcy5kb3VibGUoZmlyc3RfZHVyYXRpb24pKSwKICApICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCA3OjEyKSAlPiUKICBmaWx0ZXIodmFsdWUgPj0gMCkgJT4lICAgICAgICAgICMgZmlsdGVyIHNraXBwZWQgd29yZCBpbiBleWUgdHJhY2tpbmcgZGF0YSBmb3IgRlBSZWcKICAKICAjID09PT0gUmVtb3ZlIHNraXBwZWQgd29yZHMKICBtdXRhdGUoemVybyA9IGlmX2Vsc2UoIW1ldHJpYyAlaW4lIGMoIkZQUmVnIiwgInNraXAiKSAmIHZhbHVlID09IDAsVCwgRikpICU+JQogIGZpbHRlcih6ZXJvID09IEYpICU+JQogIAogICMgbXV0YXRlKHZhbHVlID0gaWZfZWxzZShpcy5uYSh2YWx1ZSksIGFzLmludGVnZXIoMCksIGFzLmludGVnZXIodmFsdWUpKSkgJT4lCiAgIyBtdXRhdGUodmFsdWUgPSBpZl9lbHNlKG1ldHJpYyAhPSAiRlBSZWciICYgaXMubmEodmFsdWUpLCBhcy5pbnRlZ2VyKDApLCBhcy5pbnRlZ2VyKHZhbHVlKSkpICU+JQogIGRyb3BfbmEoKSAlPiUKICBtdXRhdGUod29yZCA9IHN0cl90cmltKHdvcmQpKSAlPiUKICBtdXRhdGUoc3ViaiA9IHN0cl9yZW1vdmUoc3ViaiwgIlN1YiIpKSAlPiUKICBtdXRhdGUoc3ViaiA9IGFzLmludGVnZXIoc3ViaikpICU+JQogICAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgCiAgIyA9PT0gUmVtb3ZlIG91dGxpZXJzID4gM1NECiAgICAjIG11dGF0ZShvdXRsaWVyID0gaWZfZWxzZSghIG1ldHJpYyAlaW4lIGMoIkZQUmVnIiwgInNraXAiKSAmIHZhbHVlID4gKG1lYW4odmFsdWUpICsgMyAqIHNkKHZhbHVlKSApLCBULCBGKSkgJT4lCiAgICAjIGZpbHRlcihvdXRsaWVyID09IEYpICU+JQogIAogIHVuZ3JvdXAoKSAjJT4lCgojIEFnZ3JlZ2F0ZSBjcm9zcy1wYXJ0aWNpcGFudCBkYXRhIGZvciBhbGwgc3ViamVjdHMKcHJvdm9fZXlldHJhY2tpbmdfYWdnX2RmID0gcHJvdm9fZXlldHJhY2tpbmdfZGYgJT4lCiAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSwKICAgICAgICAgICAgICBuc3ViaiA9IGxlbmd0aCh1bmlxdWUoc3ViaikpKSAlPiUKICAgIHVuZ3JvdXAoKQoKcHJvdm9fcmF3X2RmICU+JQogIGRwbHlyOjpzZWxlY3QoSUFfUkVHUkVTU0lPTl9PVVQpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKElBX1JFR1JFU1NJT05fT1VUKSkKCnByb3ZvX3Jhd19kZiAlPiUKICBkcGx5cjo6c2VsZWN0KElBX1NLSVApICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKElBX1NLSVApKQoKYGBgCgpgYGB7cn0KCiMgU3BsaXQgdGhlIGV5ZXRyYWNraW5nIGRhdGEgaW4gdHdvIGJ5IHN1YmplY3RzIHRvIHNlZSBob3cgd2VsbCBpdCBjb3JyZWxhdGVzIHdpdGggaXRzZWxmCnByb3ZvX2V5ZXRyYWNraW5nX3N1YmoxX2RmX3RlbXAgPSBwcm92b19leWV0cmFja2luZ19kZiAlPiUKICBmaWx0ZXIoc3ViaiA8PSA0MikgJT4lCiAgbXV0YXRlKHdvcmRfdGV4dF9pZHggPSBhcy5pbnRlZ2VyKHdvcmRfdGV4dF9pZHggLSAxKSkgJT4lCiAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIHJlbmFtZSh2YWx1ZV8xID0gdmFsdWUpICMlPiUKICAjIGRwbHlyOjpzZWxlY3QoLXNlbnRfaWQsIC13b3JkX2lkeCkKCgpwcm92b19leWV0cmFja2luZ19zdWJqMV9kZiA9IG1lcmdlKHByb3ZvX2V5ZXRyYWNraW5nX3N1YmoxX2RmX3RlbXAsIG1vdHJfYWdnX2RmLCBieT1jKCJ0ZXh0X2lkIiwgIndvcmRfdGV4dF9pZHgiLCAibWV0cmljIikpICU+JQogIGFycmFuZ2UodGV4dF9pZCwgc2VudF9pZCwgd29yZF9pZHgpICU+JQogIGZpbHRlcighKHRleHRfaWQgPT0gMTMgJiB3b3JkX3RleHRfaWR4ID49IDIwICYgd29yZF90ZXh0X2lkeCA8PSA1MikpICU+JQogIGZpbHRlcighKHRleHRfaWQgPT0gMyAmIHdvcmRfdGV4dF9pZHggPj0gNDYgJiB3b3JkX3RleHRfaWR4IDw9IDU3KSkgJT4lCiAgcmVuYW1lKHdvcmQgPSB3b3JkLnkpICU+JQogIGRwbHlyOjpzZWxlY3QodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgbWV0cmljLCB3b3JkLCB2YWx1ZV8xKSAKCiMgVmlldyhwcm92b19leWV0cmFja2luZ19zdWJqMV9kZikKCnByb3ZvX2V5ZXRyYWNraW5nX3N1YmoyX2RmID0gcHJvdm9fZXlldHJhY2tpbmdfZGYgJT4lCiAgZmlsdGVyKHN1YmogPiA0MikgJT4lCiAgbXV0YXRlKHdvcmRfdGV4dF9pZHggPSBhcy5pbnRlZ2VyKHdvcmRfdGV4dF9pZHggLSAxKSkgJT4lCiAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgdW5ncm91cCgpICU+JQogICAgcmVuYW1lKHZhbHVlXzIgPSB2YWx1ZSklPiUKICBkcGx5cjo6c2VsZWN0KC1zZW50X2lkLCAtd29yZF9pZHgpCgojIFZpZXcocHJvdm9fZXlldHJhY2tpbmdfc3ViajJfZGYpCiAgCnByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgPSBtZXJnZShwcm92b19leWV0cmFja2luZ19zdWJqMl9kZiwgcHJvdm9fZXlldHJhY2tpbmdfc3ViajFfZGYsIGJ5PWMoInRleHRfaWQiLCAid29yZF90ZXh0X2lkeCIsICJtZXRyaWMiKSkgJT4lCiAgIyBmaWx0ZXIod29yZC54ID09IHdvcmQueSkgJT4lCiAgZHBseXI6OnNlbGVjdCgtd29yZC55KSAlPiUKICAjID09PSBSZW1vdmUgb3V0bGllcnMgPiAzU0QKICAjIGdyb3VwX2J5KG1ldHJpYykgJT4lCiAgIyAgIG11dGF0ZShtb3RyX291dGxpZXIgPSBpZl9lbHNlKCEgbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgdmFsdWVfMSA+IChtZWFuKHZhbHVlXzEpICsgMyAqIHNkKHZhbHVlXzEpICksIFQsIEYpKSAlPiUKICAjICAgZmlsdGVyKG1vdHJfb3V0bGllciA9PSBGKSAlPiUKICAjICAgbXV0YXRlKGV5ZXRyX291dGxpZXIgPSBpZl9lbHNlKCEgbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgdmFsdWVfMiA+IChtZWFuKHZhbHVlXzIpICsgMyAqIHNkKHZhbHVlXzIpICksIFQsIEYpKSAlPiUKICAjICAgZmlsdGVyKGV5ZXRyX291dGxpZXIgPT0gRikgJT4lCiAgIyB1bmdyb3VwKCkgJT4lCiAgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCBjKCJ2YWx1ZV8xIiwgInZhbHVlXzIiKSkgIyU+JQogICMgZHBseXI6OnNlbGVjdCgtbW90cl9vdXRsaWVyLCAtZXlldHJfb3V0bGllcikKCiMgVmlldyhwcm92b19leWV0cl9ncm91cGVkX2RmKQoKYGBgCgoKYGBge3J9CnByb3ZvX2RmID0gbWVyZ2UocHJvdm9fZXlldHJhY2tpbmdfYWdnX2RmLCBwcm92b19tb2RlbGluZ19kZiwgYnk9YygidGV4dF9pZCIsICJzZW50X2lkIiwgIndvcmRfaWR4IikpICU+JQogIG11dGF0ZSh3b3JkX3RleHRfaWR4ID0gYXMuaW50ZWdlcih3b3JkX3RleHRfaWR4IC0gMSkpICU+JQogIGFycmFuZ2UodGV4dF9pZCwgc2VudF9pZCwgd29yZF9pZHgpICU+JQogIHJlbmFtZShleWV0cl92YWx1ZSA9IHZhbHVlKSAKCnByb3ZvX2RmID0gbWVyZ2UocHJvdm9fZGYsIG1vdHJfYWdnX2RmLCBieT1jKCJ0ZXh0X2lkIiwgIndvcmRfdGV4dF9pZHgiLCAibWV0cmljIikpICU+JQphcnJhbmdlKHRleHRfaWQsIHNlbnRfaWQsIHdvcmRfaWR4KSAlPiUKICAjIGFsbW9zdCBhbGwgdGhlIHdvcmQueCAhPSB3b3JkLnkgaXMgYmVjYXVzZSBvZiBub3JtYWxpemF0aW9uIHByb2JsZW0sIHNvIHdlIGNhbiBrZWVwIHRoZW0sIGluc3RlYWQsIGRlbGV0aW5nIHNvbWUgc3BlY2lhbCBjYXNlcwpmaWx0ZXIoISh0ZXh0X2lkID09IDEzICYgd29yZF90ZXh0X2lkeCA+PSAyMCAmIHdvcmRfdGV4dF9pZHggPD0gNTIpKSAlPiUKICBmaWx0ZXIoISh0ZXh0X2lkID09IDMgJiB3b3JkX3RleHRfaWR4ID49IDQ2ICYgd29yZF90ZXh0X2lkeCA8PSA1NykpICU+JQojIGZpbHRlcih3b3JkLnggPT0gd29yZCkgIyU+JQpkcGx5cjo6c2VsZWN0KC13b3JkLngsIC13b3JkLnkpICU+JQogIAojID09PSBSZW1vdmUgb3V0bGllcnMgPiAzU0QKIyBncm91cF9ieShtZXRyaWMpICU+JQojICAgbXV0YXRlKG1vdHJfb3V0bGllciA9IGlmX2Vsc2UoISBtZXRyaWMgJWluJSBjKCJGUFJlZyIsICJza2lwIikgJiBtb3RyX3ZhbHVlID4gKG1lYW4obW90cl92YWx1ZSkgKyAzICogc2QobW90cl92YWx1ZSkgKSwgVCwgRikpICU+JQojICAgZmlsdGVyKG1vdHJfb3V0bGllciA9PSBGKSAlPiUKIyAgIG11dGF0ZShleWV0cl9vdXRsaWVyID0gaWZfZWxzZSghIG1ldHJpYyAlaW4lIGMoIkZQUmVnIiwgInNraXAiKSAmIGV5ZXRyX3ZhbHVlID4gKG1lYW4oZXlldHJfdmFsdWUpICsgMyAqIHNkKGV5ZXRyX3ZhbHVlKSApLCBULCBGKSkgJT4lCiMgICBmaWx0ZXIoZXlldHJfb3V0bGllciA9PSBGKSAlPiUKIyB1bmdyb3VwKCkgJT4lCiAgCmdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpKSAjJT4lCiMgZHBseXI6OnNlbGVjdCgtbW90cl9vdXRsaWVyLCAtZXlldHJfb3V0bGllcikKICAKIyBwcm92b19kZgpgYGAKCgojIEJheWVzaWFuIC0tIHVzZSBTdGFuIC0tIG1vdHIgJiBleWV0ciBjb3JyZWxhdGlvbgpgYGB7cn0KcHJpbnQoIkdhemUgRHVyYXRpb24iKQpnZF9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnYXplX2R1cmF0aW9uIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDEpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxKQogICkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlX2xvZyA9IGxvZyhleWV0cl92YWx1ZSksCiAgICAgICAgIG1vdHJfdmFsdWVfbG9nID0gbG9nKG1vdHJfdmFsdWUpKQpwcmludChjb3IudGVzdChnZF9kZiRleWV0cl92YWx1ZSwgZ2RfZGYkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KGdkX2RmJGV5ZXRyX3ZhbHVlX2xvZywgZ2RfZGYkbW90cl92YWx1ZV9sb2cpJGVzdGltYXRlKQojIFZpZXcoZ2RfZGYpCmBgYAoKCmBgYHtyfQpnZF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCiAgCmBgYAoKCgpgYGB7cn0KIyBjZW50ZXIgZGF0YSBhcm91bmQgMC4KCmdkX3RlbXAgPC0gZ2RfZGZbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUKICAgIyBtdXRhdGUoZXlldHJfdmFsdWUgPSBleWV0cl92YWx1ZSAtIG1lYW4oZXlldHJfdmFsdWUpLAogICAjICAgICAgbW90cl92YWx1ZSA9IG1vdHJfdmFsdWUgLSBtZWFuKG1vdHJfdmFsdWUpKSAlPiUKICBkYXRhLm1hdHJpeCgpCgpnZF90ZW1wX2xvZyA8LSBnZF9kZltjKCJleWV0cl92YWx1ZV9sb2ciLCAibW90cl92YWx1ZV9sb2ciKV0gJT4lCiBtdXRhdGUoZXlldHJfdmFsdWVfbG9nID0gZXlldHJfdmFsdWVfbG9nIC0gbWVhbihleWV0cl92YWx1ZV9sb2cpLCAKICAgICAgICBtb3RyX3ZhbHVlX2xvZyA9IG1vdHJfdmFsdWVfbG9nIC0gbWVhbihtb3RyX3ZhbHVlX2xvZykpICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChnZF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCiMgUGxvdCB0aGUgc2Vjb25kIGRhdGEgbWF0cml4IGdkX3RlbXBfbG9nCnBsb3QoZ2RfdGVtcF9sb2csIHBjaCA9IDE2LCBjb2wgPSAicmVkIiwKICAgICBtYWluID0gIkNlbnRlcmVkIExvZy1UcmFuc2Zvcm1lZCIpCgpgYGAKCgoKYGBge3IsIGV2YWw9RkFMU0V9CmdkX2RhdGEgPSBsaXN0KHg9Z2RfdGVtcCwgTj1ucm93KGdkX3RlbXApKQoKZml0X2dkID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfY29ycmVsYXRpb24uc3RhbiIsIAogIGRhdGE9Z2RfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2dkQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9nZCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfZ2F6ZV9kdXJhdGlvbl9jb3JfZHJvcDBzLnJkcyIpKQoKYGBgCgpgYGB7cn0KcHJpbnQoIkdvIFBhc3QgVGltZSIpCmdwdF9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnb19wYXN0X3RpbWUiKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIHNtb290aGluZywgaWYgaW5jbHVkZXMgMHMKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDEpCiAgKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWVfbG9nID0gbG9nKGV5ZXRyX3ZhbHVlKSwKICAgICAgICAgbW90cl92YWx1ZV9sb2cgPSBsb2cobW90cl92YWx1ZSkpCnByaW50KGNvci50ZXN0KGdwdF9kZiRleWV0cl92YWx1ZSwgZ3B0X2RmJG1vdHJfdmFsdWUpJGVzdGltYXRlKQpwcmludChjb3IudGVzdChncHRfZGYkZXlldHJfdmFsdWVfbG9nLCBncHRfZGYkbW90cl92YWx1ZV9sb2cpJGVzdGltYXRlKQoKZ3B0X2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDEyOjE1KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmdwdF90ZW1wIDwtIGdwdF9kZltjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCgpncHRfdGVtcF9sb2cgPC0gZ3B0X2RmW2MoImV5ZXRyX3ZhbHVlX2xvZyIsICJtb3RyX3ZhbHVlX2xvZyIpXSAlPiUKIG11dGF0ZShleWV0cl92YWx1ZV9sb2cgPSBleWV0cl92YWx1ZV9sb2cgLSBtZWFuKGV5ZXRyX3ZhbHVlX2xvZyksIAogICAgICAgIG1vdHJfdmFsdWVfbG9nID0gbW90cl92YWx1ZV9sb2cgLSBtZWFuKG1vdHJfdmFsdWVfbG9nKSkgJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ3B0X3RlbXAKcGxvdChncHRfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk5vdCBMb2ctVHJhbnNmb3JtZWQiKQojIFBsb3QgdGhlIHNlY29uZCBkYXRhIG1hdHJpeCBncHRfdGVtcF9sb2cKcGxvdChncHRfdGVtcF9sb2csIHBjaCA9IDE2LCBjb2wgPSAicmVkIiwKICAgICBtYWluID0gIkNlbnRlcmVkIExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBnbyBwYXN0IHRpbWUgLS0tLS0tLS0tLQpncHRfZGF0YSA9IGxpc3QoeD1ncHRfdGVtcCwgTj1ucm93KGdwdF90ZW1wKSkKZml0X2dwdCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWdwdF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZ3B0QHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9ncHQsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3JfZHJvcDBzLnJkcyIpKQpgYGAKCgpgYGB7cn0KcHJpbnQoIlRvdGFsIER1cmF0aW9uIikKdGRfZGYgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAidG90YWxfZHVyYXRpb24iKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIHNtb290aGluZywgaWYgaW5jbHVkZXMgMHMKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDEpCiAgKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWVfbG9nID0gbG9nKGV5ZXRyX3ZhbHVlKSwKICAgICAgICAgbW90cl92YWx1ZV9sb2cgPSBsb2cobW90cl92YWx1ZSkpCnByaW50KGNvci50ZXN0KHRkX2RmJGV5ZXRyX3ZhbHVlLCB0ZF9kZiRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QodGRfZGYkZXlldHJfdmFsdWVfbG9nLCB0ZF9kZiRtb3RyX3ZhbHVlX2xvZykkZXN0aW1hdGUpCgp0ZF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgp0ZF90ZW1wIDwtIHRkX2RmW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKCnRkX3RlbXBfbG9nIDwtIHRkX2RmW2MoImV5ZXRyX3ZhbHVlX2xvZyIsICJtb3RyX3ZhbHVlX2xvZyIpXSAlPiUKIG11dGF0ZShleWV0cl92YWx1ZV9sb2cgPSBleWV0cl92YWx1ZV9sb2cgLSBtZWFuKGV5ZXRyX3ZhbHVlX2xvZyksIAogICAgICAgIG1vdHJfdmFsdWVfbG9nID0gbW90cl92YWx1ZV9sb2cgLSBtZWFuKG1vdHJfdmFsdWVfbG9nKSkgJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggdGRfdGVtcApwbG90KHRkX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJOb3QgTG9nLVRyYW5zZm9ybWVkIikKIyBQbG90IHRoZSBzZWNvbmQgZGF0YSBtYXRyaXggdGRfdGVtcF9sb2cKcGxvdCh0ZF90ZW1wX2xvZywgcGNoID0gMTYsIGNvbCA9ICJyZWQiLAogICAgIG1haW4gPSAiQ2VudGVyZWQgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIHRvdGFsIGR1cmF0aW9uIC0tLS0tLS0tLS0KdGRfZGF0YSA9IGxpc3QoeD10ZF90ZW1wLCBOPW5yb3codGRfdGVtcCkpCmZpdF90ZCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPXRkX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF90ZEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfdGQsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX3RvdGFsX2R1cmF0aW9uX2Nvcl9kcm9wMHMucmRzIikpCmBgYAoKYGBge3J9CnByaW50KCJGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4iKQpyZWdfZGYgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkKcHJpbnQoY29yLnRlc3QocmVnX2RmJGV5ZXRyX3ZhbHVlLCByZWdfZGYkbW90cl92YWx1ZSkkZXN0aW1hdGUpCgojIFZpZXcocmVnX2RmKQpyZWdfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgMTI6MTMpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKcmVnX3RlbXAgPC0gcmVnX2RmW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IHRkX3RlbXAKcGxvdChyZWdfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk5vdCBMb2ctVHJhbnNmb3JtZWQiKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgRlBSZWcgLS0tLS0tLS0tLQpyZWdfZGF0YSA9IGxpc3QoeD1yZWdfdGVtcCwgTj1ucm93KHJlZ190ZW1wKSkKZml0X3JlZyA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX25vcm1hbF9yZWcuc3RhbiIsIAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfRlBSZWdfY29yX2Ryb3Awcy5yZHMiKSkKYGBgCgoKIyByYW5rIHRyYW5zZm9ybWF0aW9uIGZvciBGUFJlZwpgYGB7ciwgZXZhbD1GQUxTRX0KcmVnX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgbXV0YXRlKAogICAgZXlldHJfdmFsdWVfcmFuayA9IGlmZWxzZShleWV0cl92YWx1ZSA+IDAsIHJhbmsoZXlldHJfdmFsdWUpLCBOQSksCiAgICBtb3RyX3ZhbHVlX3JhbmsgPSBpZmVsc2UobW90cl92YWx1ZSA+IDAsIHJhbmsobW90cl92YWx1ZSksIE5BKQogICkgJT4lCiAgZHJvcF9uYSgpCiMgICBtdXRhdGUoCiMgICBleWV0cl92YWx1ZV9yYW5rID0gcmFuayhleWV0cl92YWx1ZSwgdGllcy5tZXRob2QgPSAiYXZlcmFnZSIpLAojICAgbW90cl92YWx1ZV9yYW5rID0gcmFuayhtb3RyX3ZhbHVlLCB0aWVzLm1ldGhvZCA9ICJhdmVyYWdlIikKIyApCiMgVmlldyhyZWdfZGYpCgpwcmludChjb3IudGVzdChyZWdfZGYkZXlldHJfdmFsdWVfcmFuaywgcmVnX2RmJG1vdHJfdmFsdWVfcmFuaykkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZiRleWV0cl92YWx1ZV9yYW5rLCByZWdfZGYkbW90cl92YWx1ZV9yYW5rLCBtZXRob2QgPSAia2VuZGFsbCIpKQoKCnJlZ19kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxNDoxNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpyZWdfdGVtcCA8LSByZWdfZGZbYygiZXlldHJfdmFsdWVfcmFuayIsICJtb3RyX3ZhbHVlX3JhbmsiKV0gJT4lIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IHRkX3RlbXAKcGxvdChyZWdfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIlJhbmsgVHJhbnNmb3JtZWQiKQogIApgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgRlBSZWcgUkFOSy0tLS0tLS0tLS0KcmVnX2RhdGEgPSBsaXN0KHg9cmVnX3RlbXAsIE49bnJvdyhyZWdfdGVtcCkpCmZpdF9yZWcgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9jb3JyZWxhdGlvbl9yYW5rLnN0YW4iLCAKICBkYXRhPXJlZ19kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz00LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfcmVnQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9yZWcsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl9yYW5rX2Ryb3Awcy5yZHMiKSkKYGBgCgpgYGB7cn0KcHJpbnQoInNraXAgUHJvYi4iKQpza2lwX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gInNraXAiKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIGZpbHRlcihleWV0cl92YWx1ZSA+IDAsIG1vdHJfdmFsdWUgPiAwKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMWUtNSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDFlLTUpKQpwcmludChjb3IudGVzdChza2lwX2RmJGV5ZXRyX3ZhbHVlLCBza2lwX2RmJG1vdHJfdmFsdWUpJGVzdGltYXRlKQoKIyBWaWV3KHJlZ19kZikKc2tpcF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxMykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpza2lwX3RlbXAgPC0gc2tpcF9kZltjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCB0ZF90ZW1wCnBsb3Qoc2tpcF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBza2lwIC0tLS0tLS0tLS0Kc2tpcF9kYXRhID0gbGlzdCh4PXNraXBfdGVtcCwgTj1ucm93KHNraXBfdGVtcCkpCmZpdF9za2lwID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfbm9ybWFsX3JlZy5zdGFuIiwgCiAgZGF0YT1za2lwX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9za2lwQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9za2lwLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9za2lwX2Nvcl9kcm9wMHMucmRzIikpCmBgYAoKYGBge3J9CmZpdF9nZCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dhemVfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQpmaXRfZ3B0ID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfZ29fcGFzdF90aW1lX2Nvcl9kcm9wMHMucmRzIikKZml0X3RkID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQpmaXRfcmVnID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfRlBSZWdfY29yX2Ryb3Awcy5yZHMiKQpmaXRfcmVnX3JhbmsgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9GUFJlZ19jb3JfcmFua19kcm9wMHMucmRzIikKZml0X3NraXAgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9za2lwX2Nvcl9kcm9wMHMucmRzIikKCiMgbW9kZWxzIGZvciBkcm9wIDBzCiMgZml0X2dkID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfZ2F6ZV9kdXJhdGlvbl9jb3JfZHJvcDBzLnJkcyIpCiMgZml0X2dwdCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3JfZHJvcDBzLnJkcyIpCiMgZml0X3RkID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQojIGZpdF9yZWcgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vcmFua2VkX21vdHJfZXlldHJfRlBSZWdfY29yLnJkcyIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHYXplIER1cmF0aW9uLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfZ2QpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdvIFBhc3QgVGltZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2dwdCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF90ZCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfcmVnKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4gUkFOSy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X3JlZ19yYW5rKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBTa2lwIFByb2IuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfc2tpcCkKCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnM9YygicmhvIiwgIm11IiwgInNpZ21hIiwgIm51IikpCiMgc3Rhbl9kZW5zKGZpdF9nZCwgcGFycz1jKCJyaG8iLCAibXUiLCAic2lnbWEiLCAibnUiKSwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKIyBzdGFuX3Bsb3QoZml0X2dkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpKQoKIyBHYXplIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X2dkKQpzdGFuX2RlbnMoZml0X2dkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2dkKQoKIyBHbyBQYXN0IFRpbWUKc3Rhbl90cmFjZShmaXRfZ3B0KQpzdGFuX2RlbnMoZml0X2dwdCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9ncHQpCgojIFRvdGFsIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X3RkKQpzdGFuX2RlbnMoZml0X3RkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X3RkKQoKIyBGUFJlZwpzdGFuX3RyYWNlKGZpdF9yZWcpCnN0YW5fZGVucyhmaXRfcmVnLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X3JlZykKCmBgYAoKYGBge3IsIGZpZy53aWR0aD01LCBmaWcuaGVpZ2h0PTEwLCBldmFsPUZBTFNFfQpwMSA8LSBzdGFuX3RyYWNlKGZpdF9nZCwgcGFycyA9ICdyaG8nLCBpbmNfd2FybXVwID0gRkFMU0UpCnAyIDwtIHN0YW5fZGVucyhmaXRfZ2QsIHBhcnMgPSAncmhvJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDMgPC0gc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnMgPSAnbXVbMV0nLCBpbmNfd2FybXVwID0gRkFMU0UpCnA0IDwtIHN0YW5fZGVucyhmaXRfZ2QsIHBhcnMgPSAnbXVbMV0nLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpwNSA8LSBzdGFuX3RyYWNlKGZpdF9nZCwgcGFycyA9ICdtdVsyXScsIGluY193YXJtdXAgPSBGQUxTRSkKcDYgPC0gc3Rhbl9kZW5zKGZpdF9nZCwgcGFycyA9ICdtdVsyXScsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnA3IDwtIHN0YW5fdHJhY2UoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzFdJywgaW5jX3dhcm11cCA9IEZBTFNFKQpwOCA8LSBzdGFuX2RlbnMoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzFdJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDkgPC0gc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnMgPSAnc2lnbWFbMl0nLCBpbmNfd2FybXVwID0gRkFMU0UpCnAxMCA8LSBzdGFuX2RlbnMoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzJdJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDExIDwtIHN0YW5fdHJhY2UoZml0X2dkLCBwYXJzID0gJ251JywgaW5jX3dhcm11cCA9IEZBTFNFKQpwMTIgPC0gc3Rhbl9kZW5zKGZpdF9nZCwgcGFycyA9ICdudScsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCgoKIyBVc2UgZ3JpZC5hcnJhbmdlKCkgdG8gYXJyYW5nZSB0aGUgcGxvdHMKIyBncmlkLmFycmFuZ2UocDEsIHAyLCBwMywgcDQsIHA1LCBwNiwgcDcsIHA4LCBwOSwgcDEwLCBwMTEsIHAxMiwgbmNvbD0yLCBucm93PTYpCgpgYGAKCgoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdhemUgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19nZCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZ2QsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZ2QpCmNySSA9IHF1YW50aWxlKHJob19nZCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19nZCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdvIFBhc3QgVGltZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2dwdCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZ3B0LCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2dwdCkKY3JJID0gcXVhbnRpbGUocmhvX2dwdCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19ncHQpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUb3RhbCBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX3RkID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF90ZCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob190ZCkKY3JJID0gcXVhbnRpbGUocmhvX3RkLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX3RkKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKIyByaG9fcmVnID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9yZWcsICJyaG9bMSwgMl0iKVtbMV1dKQpyaG9fcmVnID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9yZWcsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fcmVnKQpjckkgPSBxdWFudGlsZShyaG9fcmVnLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX3JlZyksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBSQU5LLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQojIHJob19yZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3JlZywgInJob1sxLCAyXSIpW1sxXV0pCnJob19yZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3JlZ19yYW5rLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX3JlZykKY3JJID0gcXVhbnRpbGUocmhvX3JlZywgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19yZWcpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU2tpcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCiMgcmhvX3JlZyA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfcmVnLCAicmhvWzEsIDJdIilbWzFdXSkKcmhvX3NraXAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3NraXAsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fc2tpcCkKY3JJID0gcXVhbnRpbGUocmhvX3NraXAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fc2tpcCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKYGBgCgoKYGBge3IsIGV2YWw9RkFMU0V9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdhemUgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmdkX3JhbmQgPC0gZXh0cmFjdChmaXRfZ2QsICJ4X3JhbmQiKVtbMV1dCiMgeF9yYW5kX2ZpbHRlcmVkIDwtIHhfcmFuZFthcHBseSh4X3JhbmQsIDEsIGZ1bmN0aW9uKHgpIGFsbCh4ID4gMCkpLF0KIyB4X3JhbmRfZmlsdGVyZWQKCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA0MDApLCB5bGltPWMoMCwgNzAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZ2RfcmFuZFssMV0sIGdkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhnZF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGdkX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UoZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHbyBQYXN0IFRpbWUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmdwdF9yYW5kIDwtIGV4dHJhY3QoZml0X2dwdCwgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA4MDApLCB5bGltPWMoMCwgMTIwMCksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJHbyBQYXN0IFRpbWUiKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZ3B0X3JhbmRbLDFdLCBncHRfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGdwdF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGdwdF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGdwdF9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFRvdGFsIER1cmF0aW9uLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQp0ZF9yYW5kIDwtIGV4dHJhY3QoZml0X3RkLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIlRvdGFsIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKHRkX3JhbmRbLDFdLCB0ZF9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHModGRfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZSh0ZF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKHRkX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfcmVnLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJGUFJlZyIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhyZWdfcmFuZFssMV0sIHJlZ19yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMocmVnX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UocmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UocmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU2tpcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnNraXBfcmFuZCA8LSBleHRyYWN0KGZpdF9za2lwLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJTa2lwIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKHNraXBfcmFuZFssMV0sIHNraXBfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHNraXBfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShza2lwX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2Uoc2tpcF9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCmBgYAoKIyBtb2RlbCBtb3RyIGV5ZXRyIEZQUmVnIGNvcnJlbGF0aW9uIChleWV0ciA8IDAuMykKYGBge3J9CnByaW50KCJGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4gYWxsIGFuZCAgPCAwLjMiKQpyZWdfZGZfYWxsID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkKCnJlZ19kZl9sb3dfZHJvcDAgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkgJT4lCiAgZmlsdGVyKGV5ZXRyX3ZhbHVlIDwgMC4zKQoKcmVnX2RmX2xvdyA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgZmlsdGVyKGV5ZXRyX3ZhbHVlID4gMCwgbW90cl92YWx1ZSA+IDApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxZS01KSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA8IDAuMykKICAjIG11dGF0ZShleWV0cl92YWx1ZSA9IGV4cChleWV0cl92YWx1ZSksCiAgICAgICAgICMgbW90cl92YWx1ZSA9IGV4cChtb3RyX3ZhbHVlKQogICAgICAgICAjICkKIyBWaWV3KHJlZ19kZikKCnByaW50KGNvci50ZXN0KHJlZ19kZl9hbGwkZXlldHJfdmFsdWUsIHJlZ19kZl9hbGwkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9hbGwkZXlldHJfdmFsdWUsIHJlZ19kZl9hbGwkbW90cl92YWx1ZSkkcC52YWx1ZSkKcHJpbnQoY29yLnRlc3QocmVnX2RmX2xvdyRleWV0cl92YWx1ZSwgcmVnX2RmX2xvdyRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QocmVnX2RmX2xvdyRleWV0cl92YWx1ZSwgcmVnX2RmX2xvdyRtb3RyX3ZhbHVlKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChyZWdfZGZfbG93X2Ryb3AwJGV5ZXRyX3ZhbHVlLCByZWdfZGZfbG93X2Ryb3AwJG1vdHJfdmFsdWUpJGVzdGltYXRlKQpwcmludChjb3IudGVzdChyZWdfZGZfbG93X2Ryb3AwJGV5ZXRyX3ZhbHVlLCByZWdfZGZfbG93X2Ryb3AwJG1vdHJfdmFsdWUpJHAudmFsdWUpCgojIFZpZXcocmVnX2RmKQpyZWdfZGZfbG93ICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDEyOjEzKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCnJlZ190ZW1wX2FsbCA8LSByZWdfZGZfYWxsW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKcmVnX3RlbXBfbG93IDwtIHJlZ19kZl9sb3dbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUgZGF0YS5tYXRyaXgoKQpyZWdfdGVtcF9sb3dfZHJvcDAgPC0gcmVnX2RmX2xvd19kcm9wMFtjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCB0ZF90ZW1wCnBsb3QocmVnX3RlbXBfbG93LCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBGUFJlZyA8IDAuMyAtLS0tLS0tLS0tCnJlZ19kYXRhID0gbGlzdCh4PXJlZ190ZW1wX2FsbCwgTj1ucm93KHJlZ190ZW1wX2FsbCkpCmZpdF9yZWcgPSBzdGFuKAogICMgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2JldGFfY29ycmVsYXRpb25fcmVnLnN0YW4iLCAKICBmaWxlID0gInN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9ub3JtYWxfcmVnLnN0YW4iLAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTQsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfRlBSZWdfY29yX2FsbF9kYXRhX2Ryb3Awcy5yZHMiKSkKYGBgCgoKIyBtb2RlbCBtb3RyIGV5ZXRyIEZQUmVnIGNvcnJlbGF0aW9uIChleWV0ciA+PSAwLjMpCmBgYHtyfQpwcmludCgiRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuID49IDAuMyIpCnJlZ19kZl9oaWdoX2Ryb3AwID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgZmlsdGVyKGV5ZXRyX3ZhbHVlID4gMCwgbW90cl92YWx1ZSA+IDApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxZS01KSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA+PSAwLjMpCgpyZWdfZGZfaGlnaCA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgZmlsdGVyKGV5ZXRyX3ZhbHVlID4gMCwgbW90cl92YWx1ZSA+IDApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxZS01KSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA+PSAwLjMpCiAgIyBtdXRhdGUoZXlldHJfdmFsdWUgPSBleHAoZXlldHJfdmFsdWUpLAogICAgICAgICAjIG1vdHJfdmFsdWUgPSBleHAobW90cl92YWx1ZSkKICAgICAgICAgIyApCiMgVmlldyhyZWdfZGYpCgpwcmludChjb3IudGVzdChyZWdfZGZfaGlnaCRleWV0cl92YWx1ZSwgcmVnX2RmX2hpZ2gkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlLCByZWdfZGZfaGlnaCRtb3RyX3ZhbHVlKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChyZWdfZGZfaGlnaF9kcm9wMCRleWV0cl92YWx1ZSwgcmVnX2RmX2hpZ2hfZHJvcDAkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9oaWdoX2Ryb3AwJGV5ZXRyX3ZhbHVlLCByZWdfZGZfaGlnaF9kcm9wMCRtb3RyX3ZhbHVlKSRwLnZhbHVlKQoKIyBWaWV3KHJlZ19kZikKcmVnX2RmX2hpZ2ggJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgMTI6MTMpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKcmVnX3RlbXBfaGlnaCA8LSByZWdfZGZfaGlnaFtjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCnJlZ190ZW1wX2hpZ2hfZHJvcDAgPC0gcmVnX2RmX2hpZ2hfZHJvcDBbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMykpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggdGRfdGVtcApwbG90KHJlZ190ZW1wX2FsbCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkZQUmVnIG5vdCBsb2dnZWQgYWxsIGRhdGEiKQpwbG90KHJlZ190ZW1wX2xvdywgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkZQUmVnIG5vdCBsb2dnZWQgZXlldHIgPCAwLjMgIikKcGxvdChyZWdfdGVtcF9oaWdoLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgbm90IGxvZ2dlZCBleWV0ciA+PSAwLjMiKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgRlBSZWcgPj0gMC4zIC0tLS0tLS0tLS0KcmVnX2RhdGEgPSBsaXN0KHg9cmVnX3RlbXBfaGlnaF9kcm9wMCwgTj1ucm93KHJlZ190ZW1wX2hpZ2hfZHJvcDApKQpmaXRfcmVnID0gc3RhbigKICAjIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9iZXRhX2NvcnJlbGF0aW9uX3JlZy5zdGFuIiwgCiAgZmlsZSA9ICJzdGFuX21vZGVscy9iaXZhcmlhdGVfbm9ybWFsX3JlZy5zdGFuIiwKICBkYXRhPXJlZ19kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz00LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfcmVnQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9yZWcsIGZpbGUgPSBwYXN0ZTAoIi4vL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9GUFJlZ19jb3JfMDMtMV9kcm9wMHMucmRzIikpCmBgYAoKCgpgYGB7cn0KZml0X21yZWdfYWxsID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfYWxsX2RhdGEucmRzIikKZml0X21yZWdfYWxsX2Ryb3AwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfYWxsX2RhdGFfZHJvcDBzLnJkcyIpCmZpdF9tcmVnX2xvdyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbl8yMDIzL21vdHJfZXlldHJfRlBSZWdfY29yXzAwLTAzLnJkcyIpCmZpdF9tcmVnX2xvd19kcm9wMCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbl8yMDIzL21vdHJfZXlldHJfRlBSZWdfY29yXzAwLTAzX2Ryb3Awcy5yZHMiKQpmaXRfbXJlZ19oaWdoID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfMDMtMS5yZHMiKQpmaXRfbXJlZ19oaWdoX2Ryb3AwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfMDMtMV9kcm9wMHMucmRzIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLiBhbGwgZGF0YSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tcmVnX2FsbCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuIGFsbCBkYXRhIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19hbGxfZHJvcDApCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLjwgMC4zLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19sb3cpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLjwgMC4zIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19sb3dfZHJvcDApCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLj49IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X21yZWdfaGlnaCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuPj0gMC4zIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19oaWdoX2Ryb3AwKQpgYGAKCmBgYHtyfQojICMgRlBSZWcgYWxsIGRhdGEKIyBzdGFuX3RyYWNlKGZpdF9tcmVnX2FsbCkKIyBzdGFuX2RlbnMoZml0X21yZWdfYWxsLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQojIHN0YW5fcGxvdChmaXRfbXJlZ19hbGwpCgojIHN0YW5fdHJhY2UoZml0X21yZWdfYWxsX2Ryb3AwKQojIHN0YW5fZGVucyhmaXRfbXJlZ19hbGxfZHJvcDAsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCiMgc3Rhbl9wbG90KGZpdF9tcmVnX2FsbF9kcm9wMCkKCiMgIyBGUFJlZyA8IDAuMwojIHN0YW5fdHJhY2UoZml0X21yZWdfbG93KQojIHN0YW5fZGVucyhmaXRfbXJlZ19sb3csIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCiMgc3Rhbl9wbG90KGZpdF9tcmVnX2xvdykKIyAKIyBzdGFuX3RyYWNlKGZpdF9tcmVnX2xvd19kcm9wMCkKIyBzdGFuX2RlbnMoZml0X21yZWdfbG93X2Ryb3AwLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQojIHN0YW5fcGxvdChmaXRfbXJlZ19sb3dfZHJvcDApCgojIEZQUmVnID4gMC4zCnN0YW5fdHJhY2UoZml0X21yZWdfaGlnaCkKc3Rhbl9kZW5zKGZpdF9tcmVnX2hpZ2gsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfbXJlZ19oaWdoKQoKc3Rhbl90cmFjZShmaXRfbXJlZ19oaWdoX2Ryb3AwKQpzdGFuX2RlbnMoZml0X21yZWdfaGlnaF9kcm9wMCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9tcmVnX2hpZ2hfZHJvcDApCmBgYAoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBhbGwgZGF0YS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21yZWdfYWxsID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2FsbCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tcmVnX2FsbCkKY3JJID0gcXVhbnRpbGUocmhvX21yZWdfYWxsLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfYWxsKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIGFsbCBkYXRhIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbXJlZ19hbGxfZHJvcDAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21yZWdfYWxsX2Ryb3AwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21yZWdfYWxsX2Ryb3AwKQpjckkgPSBxdWFudGlsZShyaG9fbXJlZ19hbGxfZHJvcDAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbXJlZ19hbGxfZHJvcDApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gPCAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19tcmVnX2xvdyA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfbXJlZ19sb3csICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fbXJlZ19sb3cpCmNySSA9IHF1YW50aWxlKHJob19tcmVnX2xvdywgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19tcmVnX2xvdyksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMyBubyAwcy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21yZWdfbG93X2Ryb3AwID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2xvd19kcm9wMCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tcmVnX2xvd19kcm9wMCkKY3JJID0gcXVhbnRpbGUocmhvX21yZWdfbG93X2Ryb3AwLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfbG93X2Ryb3AwKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21yZWdfaGlnaCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfbXJlZ19oaWdoLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21yZWdfaGlnaCkKY3JJID0gcXVhbnRpbGUocmhvX21yZWdfaGlnaCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19tcmVnX2hpZ2gpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gPj0gMC4zIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbXJlZ19oaWdoX2Ryb3AwID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2hpZ2hfZHJvcDAsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fbXJlZ19oaWdoX2Ryb3AwKQpjckkgPSBxdWFudGlsZShyaG9fbXJlZ19oaWdoX2Ryb3AwLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfaGlnaF9kcm9wMCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIGFsbCBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKbWFsbHJlZ19yYW5kIDwtIGV4dHJhY3QoZml0X21yZWdfYWxsLCAieF9yYW5kIilbWzFdXQojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1hbGxyZWdfcmFuZFssMV0sIG1hbGxyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2FsbCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtYWxscmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWFsbHJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBhbGwgZGF0YSBubyAwcy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKbWFsbHJlZ19yYW5kX2Ryb3AwIDwtIGV4dHJhY3QoZml0X21yZWdfYWxsX2Ryb3AwLCAieF9yYW5kIilbWzFdXQojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1hbGxyZWdfcmFuZF9kcm9wMFssMV0sIG1hbGxyZWdfcmFuZF9kcm9wMFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2FsbCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtYWxscmVnX3JhbmRfZHJvcDAsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWFsbHJlZ19yYW5kX2Ryb3AwLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1sb3dyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9tcmVnX2xvdywgInhfcmFuZCIpW1sxXV0KcHJpbnQobWxvd3JlZ19yYW5kKQojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1sb3dyZWdfcmFuZFssMV0sIG1sb3dyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2xvdywgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtbG93cmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWxvd3JlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMyBubyAwcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1sb3dyZWdfcmFuZF9kcm9wMCA8LSBleHRyYWN0KGZpdF9tcmVnX2xvd19kcm9wMCwgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMobWxvd3JlZ19yYW5kX2Ryb3AwWywxXSwgbWxvd3JlZ19yYW5kX2Ryb3AwWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMocmVnX3RlbXBfbG93X2Ryb3AwLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1sb3dyZWdfcmFuZF9kcm9wMCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtbG93cmVnX3JhbmRfZHJvcDAsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1oaWdocmVnX3JhbmRfc2FtcGxlcyA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgcHJpbnQobWhpZ2hyZWdfcmFuZF9zYW1wbGVzKQpzZWxlY3RlZF9pbmRpY2VzIDwtIHNhbXBsZSgxOm5yb3cobWhpZ2hyZWdfcmFuZF9zYW1wbGVzKSwgOTAwKQptaGlnaHJlZ19yYW5kIDwtIG1oaWdocmVnX3JhbmRfc2FtcGxlc1tzZWxlY3RlZF9pbmRpY2VzLCBdCiMgbWhpZ2hyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMobWhpZ2hyZWdfcmFuZFssMV0sIG1oaWdocmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhyZWdfdGVtcF9oaWdoLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1oaWdocmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWhpZ2hyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgojIHByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA+PSAwLjMgbm8gMHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptaGlnaHJlZ19yYW5kX2Ryb3AwX3NhbXBsZXMgPC0gZXh0cmFjdChmaXRfbXJlZ19oaWdoX2Ryb3AwLCAieF9yYW5kIilbWzFdXQpzZWxlY3RlZF9pbmRpY2VzIDwtIHNhbXBsZSgxOm5yb3cobWhpZ2hyZWdfcmFuZF9kcm9wMF9zYW1wbGVzKSwgOTAwKQptaGlnaHJlZ19yYW5kX2Ryb3AwIDwtIG1oaWdocmVnX3JhbmRfZHJvcDBfc2FtcGxlc1tzZWxlY3RlZF9pbmRpY2VzLCBdCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvcgpwb2ludHMobWhpZ2hyZWdfcmFuZF9kcm9wMFssMV0sIG1oaWdocmVnX3JhbmRfZHJvcDBbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhyZWdfdGVtcF9oaWdoX2Ryb3AwLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IKZGF0YUVsbGlwc2UobWhpZ2hyZWdfcmFuZF9kcm9wMCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtaGlnaHJlZ19yYW5kX2Ryb3AwLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCmBgYAoKCiMgbW9kZWwgZXllIHRyYWNraW5nIHRvIGV5ZSB0cmFja2luZyBjb3JyZWxhdGlvbgpgYGB7cn0KCnByaW50KCJHYXplIER1cmF0aW9uIikKIyBWaWV3KHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYpCgplZ2RfZGYgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnYXplX2R1cmF0aW9uIikgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lCiAgICBmaWx0ZXIodGV4dF9pZCAhPSAxOCkgJT4lCiAgICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgc21vb3RoaW5nLCBpZiBpbmNsdWRlcyAwcwogIG11dGF0ZShleWV0cl92YWx1ZV8xID0gIHBtYXgodmFsdWVfMSwgMSksCiAgICAgICAgIGV5ZXRyX3ZhbHVlXzIgPSBwbWF4KHZhbHVlXzIsIDEpCiAgKSAKcHJpbnQoY29yLnRlc3QoZWdkX2RmJGV5ZXRyX3ZhbHVlXzEsIGVnZF9kZiRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKCiMgVmlldyhlZ2RfZGYpCgplZ2RfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgNTo2KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmVnZF90ZW1wIDwtIGVnZF9kZltjKCJleWV0cl92YWx1ZV8xIiwgImV5ZXRyX3ZhbHVlXzIiKV0gJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ2RfdGVtcApwbG90KGVnZF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCgpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQplZ2RfZGF0YSA9IGxpc3QoeD1lZ2RfdGVtcCwgTj1ucm93KGVnZF90ZW1wKSkKCmZpdF9lZ2QgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9jb3JyZWxhdGlvbi5zdGFuIiwgCiAgZGF0YT1lZ2RfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VnZEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZWdkLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vY29yX2JpdmFyaWF0ZS9leWV0cl9leWV0cl9nYXplX2R1cmF0aW9uX2Nvci5yZHMiKSkKCmBgYAoKYGBge3J9CnByaW50KCJHbyBQYXN0IFRpbWUiKQoKZWdwdF9kZiA9IHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdvX3Bhc3RfdGltZSIpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGZpbHRlcih0ZXh0X2lkICE9IDE4KSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxKSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMSkKICApIApwcmludChjb3IudGVzdChlZ3B0X2RmJGV5ZXRyX3ZhbHVlXzEsIGVncHRfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCgojIFZpZXcoZWdkX2RmKQoKZWdwdF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZWdwdF90ZW1wIDwtIGVncHRfZGZbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChlZ3B0X3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KZWdwdF9kYXRhID0gbGlzdCh4PWVncHRfdGVtcCwgTj1ucm93KGVncHRfdGVtcCkpCgpmaXRfZWdwdCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWVncHRfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VncHRAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2VncHQsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9nb19wYXN0X3RpbWVfY29yLnJkcyIpKQoKYGBgCgoKYGBge3J9CnByaW50KCJUb3RhbCBEdXJhdGlvbiIpCgpldGRfZGYgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJ0b3RhbF9kdXJhdGlvbiIpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGZpbHRlcih0ZXh0X2lkICE9IDE4KSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxKSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMSkKICApIApwcmludChjb3IudGVzdChldGRfZGYkZXlldHJfdmFsdWVfMSwgZXRkX2RmJGV5ZXRyX3ZhbHVlXzIpJGVzdGltYXRlKQoKIyBWaWV3KGVnZF9kZikKCmV0ZF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZXRkX3RlbXAgPC0gZXRkX2RmW2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXRkX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJUb3RhbCBEdXJhdGlvbiBOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgoKYGBge3IsIGV2YWw9RkFMU0V9CmV0ZF9kYXRhID0gbGlzdCh4PWV0ZF90ZW1wLCBOPW5yb3coZXRkX3RlbXApKQoKZml0X2V0ZCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWV0ZF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICAjIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9ldGRAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2V0ZCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX3RvdGFsX2R1cmF0aW9uX2Nvci5yZHMiKSkKYGBgCgoKYGBge3J9CnByaW50KCJGaXNydCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4iKQoKZXJlZ19kZiA9IHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIGRpc3RpbmN0KCkgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSkpICU+JQogICMgZmlsdGVyKCEocm93X251bWJlcigpICVpbiUgYyg0NDMsIDQ0NCwgNDQ1LCA0NDYpKSkgJT4lCiAgZmlsdGVyKHRleHRfaWQgIT0gMTgpICU+JQogICAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAKICAjID09PT0gZm9yIG5vcm1hbCBkYXRhIGRyb3AwcyA9PT09CiAgIyBmaWx0ZXIodmFsdWVfMSA+IDAsIHZhbHVlXzIgPiAwKSAlPiUKICAjIG11dGF0ZShleWV0cl92YWx1ZV8xID0gIHBtYXgodmFsdWVfMSwgMWUtNSksCiAgIyAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkKICAjICkKICAKICAjID09PT0gZm9yIHJhbmtpbmcgdGhlIGRhdGEgZHJvcDBzID09PT0KICAgIG11dGF0ZSgKICAgIGV5ZXRyX3ZhbHVlXzEgPSBpZmVsc2UodmFsdWVfMSA+IDAsIHJhbmsodmFsdWVfMSksIE5BKSwKICAgIGV5ZXRyX3ZhbHVlXzIgPSBpZmVsc2UodmFsdWVfMiA+IDAsIHJhbmsodmFsdWVfMiksIE5BKQogICkgJT4lCiAgZHJvcF9uYSgpCgogICMgPT09PSBmb3IgcmFua2luZyB0aGUgZGF0YSB3LyAwcyA9PT09CiAgIyAgIG11dGF0ZSgKICAjICAgZXlldHJfdmFsdWVfMSA9IHJhbmsodmFsdWVfMSwgdGllcy5tZXRob2QgPSAiYXZlcmFnZSIpLAogICMgICBleWV0cl92YWx1ZV8yID0gcmFuayh2YWx1ZV8yLCB0aWVzLm1ldGhvZCA9ICJhdmVyYWdlIikKICAjICkKCgpwcmludChjb3IudGVzdChlcmVnX2RmJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCgojIFZpZXcoZWdkX2RmKQoKZXJlZ19kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZXJlZ190ZW1wIDwtIGVyZWdfZGZbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRyb3BfbmEoKSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXJlZ190ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBGUFJlZyAtLS0tLS0tLS0tCgojIFZpZXcoZXJlZ190ZW1wKQplcmVnX2RhdGEgPSBsaXN0KHg9ZXJlZ190ZW1wLCBOPW5yb3coZXJlZ190ZW1wKSkKZml0X2VyZWcgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9jb3JyZWxhdGlvbl9yYW5rLnN0YW4iLCAKICBkYXRhPWVyZWdfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZXJlZ0BzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZXJlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9yYW5rX2Ryb3Awcy5yZHMiKSkKYGBgCgpgYGB7cn0KcHJpbnQoIlNraXAgUHJvYi4iKQoKZXNraXBfZGYgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJza2lwIikgJT4lIGRpc3RpbmN0KCkgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSkpICU+JQogICMgZmlsdGVyKCEocm93X251bWJlcigpICVpbiUgYyg0NDMsIDQ0NCwgNDQ1LCA0NDYpKSkgJT4lCiAgZmlsdGVyKHRleHRfaWQgIT0gMTgpICU+JQogICAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKQogIAogICMgPT09PSBmb3Igbm9ybWFsIGRhdGEgZHJvcDBzID09PT0KICAjIGZpbHRlcih2YWx1ZV8xID4gMCwgdmFsdWVfMiA+IDApICU+JQogICMgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAjICAgICAgICBleWV0cl92YWx1ZV8yID0gcG1heCh2YWx1ZV8yLCAxZS01KQogICMgKQogIAogICMgPT09PSBmb3IgcmFua2luZyB0aGUgZGF0YSBkcm9wMHMgPT09PQogICMgICBtdXRhdGUoCiAgIyAgIGV5ZXRyX3ZhbHVlXzEgPSBpZmVsc2UodmFsdWVfMSA+IDAsIHJhbmsodmFsdWVfMSksIE5BKSwKICAjICAgZXlldHJfdmFsdWVfMiA9IGlmZWxzZSh2YWx1ZV8yID4gMCwgcmFuayh2YWx1ZV8yKSwgTkEpCiAgIyApICU+JQogICMgZHJvcF9uYSgpCgogICMgPT09PSBmb3IgcmFua2luZyB0aGUgZGF0YSB3LyAwcyA9PT09CiAgIyAgIG11dGF0ZSgKICAjICAgZXlldHJfdmFsdWVfMSA9IHJhbmsodmFsdWVfMSwgdGllcy5tZXRob2QgPSAiYXZlcmFnZSIpLAogICMgICBleWV0cl92YWx1ZV8yID0gcmFuayh2YWx1ZV8yLCB0aWVzLm1ldGhvZCA9ICJhdmVyYWdlIikKICAjICkKCgpwcmludChjb3IudGVzdChlc2tpcF9kZiR2YWx1ZV8xLCBlc2tpcF9kZiR2YWx1ZV8yKSRlc3RpbWF0ZSkKCgplc2tpcF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZXNraXBfdGVtcCA8LSBlc2tpcF9kZltjKCJ2YWx1ZV8xIiwgInZhbHVlXzIiKV0gJT4lCiAgZHJvcF9uYSgpICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChlc2tpcF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiU2tpcCBOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIFNraXAgLS0tLS0tLS0tLQoKIyBWaWV3KGVyZWdfdGVtcCkKZXNraXBfZGF0YSA9IGxpc3QoeD1lc2tpcF90ZW1wLCBOPW5yb3coZXNraXBfdGVtcCkpCmZpdF9lc2tpcCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX25vcm1hbF9yZWcuc3RhbiIsIAogIGRhdGE9ZXNraXBfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZXNraXBAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2Vza2lwLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfc2tpcF9jb3JfZHJvcDBzLnJkcyIpKQpgYGAKCgoKYGBge3J9CmZpdF9lZ2QgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfZ2F6ZV9kdXJhdGlvbl9jb3JfZHJvcDBzLnJkcyIpCmZpdF9lZ3B0ID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3JfZHJvcDBzLnJkcyIpCmZpdF9ldGQgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQpmaXRfZXJlZyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfZHJvcDBzLnJkcyIpCmZpdF9lc2tpcCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9za2lwX2Nvcl9kcm9wMHMucmRzIikKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VnZCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR28gUGFzdCBUaW1lLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfZWdwdCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9ldGQpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWcpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFNraXAgUHJvYi4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9lc2tpcCkKYGBgCgoKYGBge3IsIGV2YWw9RkFMU0V9CiMgc3Rhbl90cmFjZShmaXRfZWdkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpKQojIHN0YW5fZGVucyhmaXRfZWdkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQojIHN0YW5fcGxvdChmaXRfZWdkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpKQoKIyBHYXplIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X2VnZCkKc3Rhbl9kZW5zKGZpdF9lZ2QsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZWdkKQoKIyBHbyBQYXN0IFRpbWUKc3Rhbl90cmFjZShmaXRfZWdwdCkKc3Rhbl9kZW5zKGZpdF9lZ3B0LCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VncHQpCgojIFRvdGFsIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X2V0ZCkKc3Rhbl9kZW5zKGZpdF9ldGQsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZXRkKQoKIyBGUFJlZwpzdGFuX3RyYWNlKGZpdF9lcmVnKQpzdGFuX2RlbnMoZml0X2VyZWcsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZXJlZykKYGBgCgoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdhemUgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lZ2QgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VnZCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lZ2QpCmNySSA9IHF1YW50aWxlKHJob19lZ2QsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZWdkKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR28gUGFzdCBUaW1lLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZWdwdCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZWdwdCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lZ3B0KQpjckkgPSBxdWFudGlsZShyaG9fZWdwdCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19lZ3B0KSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19ldGQgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2V0ZCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19ldGQpCmNySSA9IHF1YW50aWxlKHJob19ldGQsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXRkKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VyZWcsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZXJlZykKY3JJID0gcXVhbnRpbGUocmhvX2VyZWcsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXJlZyksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFNraXAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZXNraXAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2Vza2lwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2Vza2lwKQpjckkgPSBxdWFudGlsZShyaG9fZXNraXAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXNraXApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQpgYGAKCgpgYGB7ciwgZXZhbD1GQUxTRX0KcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWdkX3JhbmQgPC0gZXh0cmFjdChmaXRfZWdkLCAieF9yYW5kIilbWzFdXQojIHhfcmFuZF9maWx0ZXJlZCA8LSB4X3JhbmRbYXBwbHkoeF9yYW5kLCAxLCBmdW5jdGlvbih4KSBhbGwoeCA+IDApKSxdCiMgeF9yYW5kX2ZpbHRlcmVkCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgNDAwKSwgeWxpbT1jKDAsIDcwMCksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDEiLCB5bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSAyIiwgbWFpbiA9ICJHYXplIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGVnZF9yYW5kWywxXSwgZWdkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlZ2RfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHbyBQYXN0IFRpbWUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVncHRfcmFuZCA8LSBleHRyYWN0KGZpdF9lZ3B0LCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMSIsIHlsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDIiLCBtYWluID0gIkdvIFBhc3QgVGltZSIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlZ3B0X3JhbmRbLDFdLCBlZ3B0X3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlZ3B0X3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZWdwdF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVncHRfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUb3RhbCBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZXRkX3JhbmQgPC0gZXh0cmFjdChmaXRfZXRkLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMSIsIHlsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDIiLCBtYWluID0gIlRvdGFsIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGV0ZF9yYW5kWywxXSwgZXRkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhldGRfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShldGRfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShldGRfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQplcmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfZXJlZywgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSAxIiwgeWxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMiIsIG1haW4gPSAiRmlyc3QgUGFzcyBSZWdyZXNzaW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGVyZWdfcmFuZFssMV0sIGVyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGVyZWdfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlcmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UoZXJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKYGBgCgoKIyBCYXllc2lhbiAtLSBjb3JyZWxhdGlvbiBiZXR3ZWVuIE1vVFIgYW5kIHdvcmQgbGV2ZWwgc3RhdGlzdGljcwpgYGB7cn0KcHJpbnQoIkxvZyBGcmVxdWVuY3kiKQpzdGF0c19jb3JfZGYgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiZ2F6ZV9kdXJhdGlvbiIpICU+JSBzcHJlYWQobWVhc3VyZSwgdmFsdWUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRtb3RyX3ZhbHVlLCBzdGF0c19jb3JfZGYkZnJlcSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRleWV0cl92YWx1ZSwgc3RhdHNfY29yX2RmJGZyZXEpJGVzdGltYXRlKQoKIyBWaWV3KHN0YXRzX2Nvcl9kZikKc3RhdHNfY29yX2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIGMoNywgMTMpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCm1mcmVxX3RlbXAgPC0gc3RhdHNfY29yX2RmW2MoIm1vdHJfdmFsdWUiLCAiZnJlcSIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCmVmcmVxX3RlbXAgPC0gc3RhdHNfY29yX2RmW2MoImV5ZXRyX3ZhbHVlIiwgImZyZXEiKV0gJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ2RfdGVtcApwbG90KG1mcmVxX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJNb1RSIFJUcyBhbmQgV29yZCBGcmVxdWVuY3kiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZWZyZXFfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkV5ZVRSIFJUcyBhbmQgV29yZCBGcmVxdWVuY3kiKQoKYGBgCiMgbW90ciAmIGZyZXF1ZW5jeQpgYGB7ciwgZXZhbD1GQUxTRX0KbWZyZXFfZGF0YSA9IGxpc3QoeD1tZnJlcV90ZW1wLCBOPW5yb3cobWZyZXFfdGVtcCkpCgpmaXRfbWZyZXEgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPW1mcmVxX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X21mcmVxQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9tZnJlcSwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZnJlcV9jb3IucmRzIikpCmBgYAoKIyBleWV0ciAmIGZyZXF1ZW5jeQpgYGB7ciwgZXZhbD1GQUxTRX0KZWZyZXFfZGF0YSA9IGxpc3QoeD1lZnJlcV90ZW1wLCBOPW5yb3coZWZyZXFfdGVtcCkpCgpmaXRfZWZyZXEgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWVmcmVxX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VmcmVxQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9lZnJlcSwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2ZyZXFfY29yLnJkcyIpKQpgYGAKCmBgYHtyfQpwcmludCgiTGVuZ3RoIikKc3RhdHNfY29yX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdhemVfZHVyYXRpb24iKSAlPiUgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKQpwcmludChjb3IudGVzdChzdGF0c19jb3JfZGYkbW90cl92YWx1ZSwgc3RhdHNfY29yX2RmJGxlbikkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRleWV0cl92YWx1ZSwgc3RhdHNfY29yX2RmJGxlbikkZXN0aW1hdGUpCgojIFZpZXcoc3RhdHNfY29yX2RmKQpzdGF0c19jb3JfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYyg5LCAxMykpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKbWxlbl90ZW1wIDwtIHN0YXRzX2Nvcl9kZltjKCJtb3RyX3ZhbHVlIiwgImxlbiIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCmVsZW5fdGVtcCA8LSBzdGF0c19jb3JfZGZbYygiZXlldHJfdmFsdWUiLCAibGVuIildICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChtbGVuX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJNb1RSIFJUcyBhbmQgV29yZCBMZW5ndGgiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZWxlbl90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRXllVFIgUlRzIGFuZCBXb3JkIExlbmd0aCIpCmBgYAoKIyBtb3RyICYgbGVuZ3RoCmBgYHtyLCBldmFsPUZBTFNFfQptbGVuX2RhdGEgPSBsaXN0KHg9bWxlbl90ZW1wLCBOPW5yb3cobWxlbl90ZW1wKSkKCmZpdF9tbGVuID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9zdGF0c19jb3JyZWxhdGlvbl9sZW5fbm9ybWFsLnN0YW4iLCAKICBkYXRhPW1sZW5fZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgIyB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfbWxlbkBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfbWxlbiwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfbGVuX2Nvci5yZHMiKSkKCmBgYAoKIyBleWV0ciAmIGxlbmd0aApgYGB7ciwgZXZhbD1GQUxTRX0KZWxlbl9kYXRhID0gbGlzdCh4PWVsZW5fdGVtcCwgTj1ucm93KGVsZW5fdGVtcCkpCgpmaXRfZWxlbiA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvc3RhdHNfY29ycmVsYXRpb25fbGVuX25vcm1hbC5zdGFuIiwgCiAgZGF0YT1lbGVuX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VsZW5Ac3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2VsZW4sIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9sZW5fY29yLnJkcyIpKQpgYGAKCgpgYGB7cn0KcHJpbnQoIlN1cnByaXNhbCIpCnN0YXRzX2Nvcl9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnYXplX2R1cmF0aW9uIikgJT4lIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkKcHJpbnQoY29yLnRlc3Qoc3RhdHNfY29yX2RmJG1vdHJfdmFsdWUsIHN0YXRzX2Nvcl9kZiRzdXJwKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3Qoc3RhdHNfY29yX2RmJGV5ZXRyX3ZhbHVlLCBzdGF0c19jb3JfZGYkc3VycCkkZXN0aW1hdGUpCgojIFZpZXcoc3RhdHNfY29yX2RmKQpzdGF0c19jb3JfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYyg4LCAxMykpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKbXN1cnBfdGVtcCA8LSBzdGF0c19jb3JfZGZbYygibW90cl92YWx1ZSIsICJzdXJwIildICU+JQogIGRhdGEubWF0cml4KCkKZXN1cnBfdGVtcCA8LSBzdGF0c19jb3JfZGZbYygiZXlldHJfdmFsdWUiLCAic3VycCIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QobXN1cnBfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk1vVFIgUlRzIGFuZCBTdXJwcmlzYWwiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXN1cnBfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkV5ZVRSIFJUcyBhbmQgU3VycHJpc2FsIikKYGBgCiMgbW90ciAmIHN1cnByaXNhbApgYGB7ciwgZXZhbD1GQUxTRX0KbXN1cnBfZGF0YSA9IGxpc3QoeD1tc3VycF90ZW1wLCBOPW5yb3cobXN1cnBfdGVtcCkpCgpmaXRfbXN1cnAgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPW1zdXJwX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X21zdXJwQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9tc3VycCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfc3VycF9jb3IucmRzIikpCgpgYGAKCiMgZXlldHIgJiBzdXJwcmlzYWwKYGBge3IsIGV2YWw9RkFMU0V9CmVzdXJwX2RhdGEgPSBsaXN0KHg9ZXN1cnBfdGVtcCwgTj1ucm93KGVzdXJwX3RlbXApKQoKZml0X2VzdXJwID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9zdGF0c19jb3JyZWxhdGlvbi5zdGFuIiwgCiAgZGF0YT1lc3VycF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICAjIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9lc3VycEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZXN1cnAsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9zdXJwX2Nvci5yZHMiKSkKCmBgYAoKCmBgYHtyfQpmaXRfbWZyZXEgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9mcmVxX2Nvci5yZHMiKQpmaXRfZWZyZXEgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZnJlcV9jb3IucmRzIikKZml0X21sZW4gPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9sZW5fY29yLnJkcyIpCmZpdF9lbGVuID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2xlbl9jb3IucmRzIikKZml0X21zdXJwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfc3VycF9jb3IucmRzIikKZml0X2VzdXJwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX3N1cnBfY29yLnJkcyIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTG9nIEZyZXF1ZW5jeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tZnJlcSkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXllVFIgJiBMb2cgRnJlcXVlbmN5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VmcmVxKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X21sZW4pCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VsZW4pCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBTdXJwcmlzYWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXN1cnApCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgU3VycHJpc2FsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VzdXJwKQoKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyBNb1RSICYgTG9nIEZyZXEKc3Rhbl90cmFjZShmaXRfbWZyZXEpCnN0YW5fZGVucyhmaXRfbWZyZXEsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfbWZyZXEpCgojIEV5ZVRSICYgTG9nIEZyZXEKc3Rhbl90cmFjZShmaXRfZWZyZXEpCnN0YW5fZGVucyhmaXRfZWZyZXEsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZWZyZXEpCgojIE1vVFIgJiBMZW4Kc3Rhbl90cmFjZShmaXRfbWxlbikKc3Rhbl9kZW5zKGZpdF9tbGVuLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X21sZW4pCgojIEV5ZVRSICYgTGVuCnN0YW5fdHJhY2UoZml0X2VsZW4pCnN0YW5fZGVucyhmaXRfZWxlbiwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lbGVuKQoKIyBNb1RSICYgU3VycHJpc2FsCnN0YW5fdHJhY2UoZml0X21zdXJwKQpzdGFuX2RlbnMoZml0X21zdXJwLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X21zdXJwKQoKIyBFeWVUUiAmIFN1cnByaXNhbApzdGFuX3RyYWNlKGZpdF9lc3VycCkKc3Rhbl9kZW5zKGZpdF9lc3VycCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lc3VycCkKCmBgYAoKCmBgYHtyfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTG9nIEZyZXEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbWZyZXEgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21mcmVxLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21mcmVxKQpjckkgPSBxdWFudGlsZShyaG9fbWZyZXEsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbWZyZXEpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIExvZyBGcmVxIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VmcmVxID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lZnJlcSwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lZnJlcSkKY3JJID0gcXVhbnRpbGUocmhvX2VmcmVxLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VmcmVxKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTW9UUiAmIExlbmd0aCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19tbGVuID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tbGVuLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21sZW4pCmNySSA9IHF1YW50aWxlKHJob19tbGVuLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21sZW4pLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIExlbmd0aCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lbGVuID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lbGVuLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2VsZW4pCmNySSA9IHF1YW50aWxlKHJob19lbGVuLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VsZW4pLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgU3VycHJpc2FsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21zdXJwID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tc3VycCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tc3VycCkKY3JJID0gcXVhbnRpbGUocmhvX21zdXJwLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21zdXJwKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXllVFIgJiBTdXJwcmlzYWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZXN1cnAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VzdXJwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2VzdXJwKQpjckkgPSBxdWFudGlsZShyaG9fZXN1cnAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXN1cnApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQoKYGBgCgoKCmBgYHtyLGV2YWw9RkFMU0V9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBMb2cgRnJlcXVlbmN5LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptZnJlcV9yYW5kIDwtIGV4dHJhY3QoZml0X21mcmVxLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMiksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiTW9UUiB2YWx1ZSIsIHlsYWIgPSAiTG9nIEZyZXF1ZW5jeSIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtZnJlcV9yYW5kWywxXSwgbWZyZXFfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKG1mcmVxX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UobWZyZXFfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtZnJlcV9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTG9nIEZyZXF1ZW5jeS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWZyZXFfcmFuZCA8LSBleHRyYWN0KGZpdF9lZnJlcSwgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA1MDApLCB5bGltPWMoMCwgMTIpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTG9nIEZyZXF1ZW5jeSIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlZnJlcV9yYW5kWywxXSwgZWZyZXFfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGVmcmVxX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZWZyZXFfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlZnJlcV9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBMZW5ndGggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptbGVuX3JhbmQgPC0gZXh0cmFjdChmaXRfbWxlbiwgInhfcmFuZCIpW1sxXV0KIyBtbGVuX3JhbmQKCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA4MDApLCB5bGltPWMoMCwgMjApLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIk1vVFIgdmFsdWUiLCB5bGFiID0gIldvcmQgTGVuZ3RoIiwgbWFpbiA9ICJHYXplIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1sZW5fcmFuZFssMV0sIG1sZW5fcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKG1sZW5fdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtbGVuX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWxlbl9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWxlbl9yYW5kIDwtIGV4dHJhY3QoZml0X2VsZW4sICJ4X3JhbmQiKVtbMV1dCiMgZWxlbl9yYW5kCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWVUUiB2YWx1ZSIsIHlsYWIgPSAiV29yZCBMZW5ndGgiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWxlbl9yYW5kWywxXSwgZWxlbl9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZWxlbl90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVsZW5fcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlbGVuX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTW9UUiAmIFN1cnByaXNhbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1zdXJwX3JhbmQgPC0gZXh0cmFjdChmaXRfbXN1cnAsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJNb1RSIHZhbHVlIiwgeWxhYiA9ICJXb3JkIFN1cnByaXNhbCIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtc3VycF9yYW5kIFssMV0sIG1zdXJwX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhtc3VycF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1zdXJwX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobXN1cnBfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIFN1cnByaXNhbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVzdXJwX3JhbmQgPC0gZXh0cmFjdChmaXRfZXN1cnAsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWVUUiB2YWx1ZSIsIHlsYWIgPSAiV29yZCBTdXJwcmlzYWwiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZXN1cnBfcmFuZCBbLDFdLCBlc3VycF9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZXN1cnBfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlc3VycF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVzdXJwX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKYGBgCgoKYGBge3J9CnByaW50KCJFeWVUUiB2cy4gRXllVFIgRmlzcnQgUGFzcyBSZWdyZXNzaW9uIFByb2IuIDwgMC4zICIpCgplcmVnX2RmID0gcHJvdm9fZXlldHJfZ3JvdXBlZF9kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgZGlzdGluY3QoKSAlPiUgI2dyb3VwX2J5KHRleHRfaWQsIG1ldHJpYywgbWVhc3VyZSkgJT4lCiAgIyBzdW1tYXJpemUodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgZmlsdGVyKCEocm93X251bWJlcigpICVpbiUgYyg0NDMsIDQ0NCwgNDQ1LCA0NDYpKSkgJT4lCiAgICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgc21vb3RoaW5nLCBpZiBpbmNsdWRlcyAwcwogIG11dGF0ZShleWV0cl92YWx1ZV8xID0gIHBtYXgodmFsdWVfMSwgMWUtNSksCiAgICAgICAgIGV5ZXRyX3ZhbHVlXzIgPSBwbWF4KHZhbHVlXzIsIDFlLTUpKQoKZXJlZ19kZl9sb3cgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSBkaXN0aW5jdCgpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBmaWx0ZXIoIShyb3dfbnVtYmVyKCkgJWluJSBjKDQ0MywgNDQ0LCA0NDUsIDQ0NikpKSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZV8xIDwgMC4zKQojIFZpZXcoZXJlZ19kZl9sb3cpCgplcmVnX2RmX2hpZ2ggPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSBkaXN0aW5jdCgpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBmaWx0ZXIoIShyb3dfbnVtYmVyKCkgJWluJSBjKDQ0MywgNDQ0LCA0NDUsIDQ0NikpKSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZV8xID49IDAuMykKIyBWaWV3KGVyZWdfZGZfaGlnaCkgCgpwcmludChjb3IudGVzdChlcmVnX2RmJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KGVyZWdfZGYkZXlldHJfdmFsdWVfMSwgZXJlZ19kZiRleWV0cl92YWx1ZV8yKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChlcmVnX2RmX2xvdyRleWV0cl92YWx1ZV8xLCBlcmVnX2RmX2xvdyRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9sb3ckZXlldHJfdmFsdWVfMSwgZXJlZ19kZl9sb3ckZXlldHJfdmFsdWVfMikkcC52YWx1ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGZfaGlnaCRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGZfaGlnaCRleWV0cl92YWx1ZV8yKSRwLnZhbHVlKQoKIyBWaWV3KGVnZF9kZikKCmVyZWdfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgNTo2KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmVyZWdfdGVtcCA8LSBlcmVnX2RmW2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkcm9wX25hKCkgJT4lCiAgZGF0YS5tYXRyaXgoKQplcmVnX3RlbXBfbG93IDwtIGVyZWdfZGZfbG93W2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkcm9wX25hKCkgJT4lCiAgZGF0YS5tYXRyaXgoKQplcmVnX3RlbXBfaGlnaCA8LSBlcmVnX2RmX2hpZ2hbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRyb3BfbmEoKSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAzKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXJlZ190ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgYWxsIGRhdGEgTm90IExvZy1UcmFuc2Zvcm1lZCIpCnBsb3QoZXJlZ190ZW1wX2xvdywgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkZQUmVnIDwgMC4zIE5vdCBMb2ctVHJhbnNmb3JtZWQiKQpwbG90KGVyZWdfdGVtcF9oaWdoLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgPiAwLjMgTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgZXlldHIgdnMuIGV5ZXRyIEZQUmVnIDwwLjMgJiA+PTAuMyAtLS0tLS0tLS0tCnJlZ19kYXRhID0gbGlzdCh4PWVyZWdfdGVtcCwgTj1ucm93KGVyZWdfdGVtcCkpCmZpdF9yZWcgPSBzdGFuKAogICMgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2JldGFfY29ycmVsYXRpb25fcmVnLnN0YW4iLCAKICBmaWxlID0gInN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9ub3JtYWxfcmVnLnN0YW4iLAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTQsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YS5yZHMiKSkKYGBgCgoKCiMgZXhwbG9yYXRvcnk6IGRpdmlkZSBleWUgdHJhY2tpbmcgcmVncmVzc2lvbiBkYXRhIGludG8gdHdvIHBhcnRzLgpgYGB7cn0KIyBmaXRfZXJlZ19hbGwgPSByZWFkUkRTKCIuL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YS5yZHMiKQpmaXRfZXJlZ19hbGwgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfRlBSZWdfY29yLnJkcyIpCmZpdF9lcmVnX2xvdyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfMDAtMDMucmRzIikKZml0X2VyZWdfaGlnaCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfMDMtMS5yZHMiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuIGFsbCBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWdfYWxsKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi48IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWdfbG93KQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4+PSAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9lcmVnX2hpZ2gpCgpgYGAKCgpgYGB7cn0KIyAjIEZQUmVnIGFsbCBkYXRhCnN0YW5fdHJhY2UoZml0X2VyZWdfYWxsKQpzdGFuX2RlbnMoZml0X2VyZWdfYWxsLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VyZWdfYWxsKQoKIyAjIEZQUmVnIDwgMC4zCnN0YW5fdHJhY2UoZml0X2VyZWdfbG93KQpzdGFuX2RlbnMoZml0X2VyZWdfbG93LCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VyZWdfbG93KQoKIyBGUFJlZyA+PSAwLjMKc3Rhbl90cmFjZShmaXRfZXJlZ19oaWdoKQpzdGFuX2RlbnMoZml0X2VyZWdfaGlnaCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lcmVnX2hpZ2gpCmBgYAoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBhbGwgZGF0YS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWdfYWxsID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lcmVnX2FsbCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2FsbCkKY3JJID0gcXVhbnRpbGUocmhvX2VyZWdfYWxsLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VyZWdfYWxsKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWdfbG93ID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lcmVnX2xvdywgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2xvdykKY3JJID0gcXVhbnRpbGUocmhvX2VyZWdfbG93LCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VyZWdfbG93KSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA+PSAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lcmVnX2hpZ2ggPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VyZWdfaGlnaCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2hpZ2gpCmNySSA9IHF1YW50aWxlKHJob19lcmVnX2hpZ2gsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXJlZ19oaWdoKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQpgYGAKCmBgYHtyfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gYWxsIGRhdGEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQplYWxscmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfZXJlZ19hbGwsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWFsbHJlZ19yYW5kWywxXSwgZWFsbHJlZ19yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZXJlZ190ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVhbGxyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlYWxscmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIDwgMC4zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWxvd3JlZ19yYW5kIDwtIGV4dHJhY3QoZml0X2VyZWdfbG93LCAieF9yYW5kIilbWzFdXQojIHByaW50KGVsb3dyZWdfcmFuZCkKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJGUFJlZyIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlbG93cmVnX3JhbmRbLDFdLCBlbG93cmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlcmVnX3RlbXBfbG93LCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVsb3dyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlbG93cmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVoaWdocmVnX3JhbmRfc2FtcGxlcyA8LSBleHRyYWN0KGZpdF9lcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgcHJpbnQobWhpZ2hyZWdfcmFuZF9zYW1wbGVzKQpzZWxlY3RlZF9pbmRpY2VzIDwtIHNhbXBsZSgxOm5yb3coZWhpZ2hyZWdfcmFuZF9zYW1wbGVzKSwgOTAwKQplaGlnaHJlZ19yYW5kIDwtIGVoaWdocmVnX3JhbmRfc2FtcGxlc1tzZWxlY3RlZF9pbmRpY2VzLCBdCiMgbWhpZ2hyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWhpZ2hyZWdfcmFuZFssMV0sIGVoaWdocmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlcmVnX3RlbXBfaGlnaCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlaGlnaHJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVoaWdocmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKYGBgCg==